为泛型类型实现ninject提供程序



使用ninject,我想为依赖于ApplicationDbContext:的MyRepository类创建一个提供程序

public class MyRepository<TEntity> : IMyRepository<TEntity>
where TEntity : MyBaseEntity
{
private ApplicationDbContext _dbContext;
public MyRepository(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
// ...
}

我看过这个文件,它解释了应该如何创建提供者,但我不确定:

  1. 如何将ApplicationDbConext参数传递给提供程序
  2. 如何实例化泛型类型

这是我的尝试:

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();

相关内容

  • 没有找到相关文章

最新更新