使用ninject,我想为依赖于ApplicationDbContext
:的MyRepository
类创建一个提供程序
public class MyRepository<TEntity> : IMyRepository<TEntity>
where TEntity : MyBaseEntity
{
private ApplicationDbContext _dbContext;
public MyRepository(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
// ...
}
我看过这个文件,它解释了应该如何创建提供者,但我不确定:
- 如何将
ApplicationDbConext
参数传递给提供程序 - 如何实例化泛型类型
这是我的尝试:
public class MyRepositoryProvider : Provider<MyRepository>
{
protected override MyRepository CreateInstance(IContext context)
{
// how to create a generic instance of type T?
MyRepository myRepository = new MyRepository<T>(/*need ApplicationDbContext*/);
return myRepository;
}
}
我不确定是否可以为泛型类型创建提供程序。如果不是,有人能展示一下如何使用工厂界面来实现这一点吗?
注意:我已经创建了这个代码评审,解释了为什么我需要一个提供者
因为在这种情况下,目标实现类型是提供者已知的。
然后,您可以从请求的类型中获取泛型类型,并使用它来构造所需的实现。
public class MyRepositoryProvider : IProvider {
private ApplicationDbContext _applicationDbContext;
public MyRepositoryProvider(ApplicationDbContext applicationDbContext) {
_applicationDbContext = applicationDbContext;
}
Type Type => typeof(MyRepository<>);
public object Create(IContext context) {
var genericArguments = context.GenericArguments; //TEntity
var genericType = this.Type.MakeGenericType(genericArguments); //MyRepository<TEntity>
//using reflection to do new MyRepository<TEntity>(_applicationDbContext)
return Activator.CreateInstance(genericType, _applicationDbContext);
}
}
Activator
是在假设实现具有公共构造函数的情况下使用的,正如原始示例中的代码所暗示的那样。如果不是公共的,那么可以使用反射来查找构造并调用它
提供者已向内核注册
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
kernel.Bind(typeof(IMyRepository<>)).ToProvider(typeof(MyRepositoryProvider)).InRequestScope();
哪个告诉内核在解析抽象时使用提供程序
IMyRepository<MyEntity> repository = kernel.Get<IMyRepository<MyEntity>>();
我设法为我的泛型类型创建了一个提供程序:
public class MyRepositoryProvider<TEntity> : Provider<IMyRepository<TEntity>>
where TEntity : MyBaseEntity
{
private ApplicationDbContext _applicationDbContext;
public MyRepositoryProvider(ApplicationDbContext applicationDbContext)
{
_applicationDbContext = applicationDbContext;
}
protected override IMyRepository<TEntity> CreateInstance(IContext context)
{
return new MyRepository<TEntity>(_applicationDbContext);
}
}
这就是绑定的样子:
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
kernel.Bind(typeof(IMyRepository<>)).ToProvider(typeof(MyRepositoryProvider<>)).InRequestScope();