如何使用工厂实例化接口
How to use a factory to instantiate an interface
我有一个工厂来创建通用服务:
public static class AdPersisterFactory<TEntity>
where TEntity : AdBase
{
public static AdPersister<TEntity> Create(ApplicationDbContext dbContext)
{
AdRepository<TEntity> adRepository = new AdRepository<TEntity>(dbContext);
IAdImagePersister s3AdImagePersister = new S3AdImagePersister();
AdPersister<TEntity> adPersister = new AdPersister<TEntity>(adRepository, s3AdImagePersister);
return adPersister;
}
}
我想使用 ninject(版本 3),如何将 IAdPersister
绑定到上述工厂创建的实例...这是我的 DI 代码:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
// I have tried the following which does not compile
// kernel.Bind(typeof(IAdPersister<>)).ToMethod(ctx => AdPersisterFactory<>.Create(new ApplicationDbContext()));
}
这是针对 ASp.NET MVC 应用程序的,因此理想情况下我不想使用新的 ApplicationDbContext
,而是使用 RequestScope
中存在的相同 ApplicationDbContext
。
我也看到了Ninject.Extensions.Factory但是我不确定how/if我可以在这种情况下使用它
如果您愿意重构为更 SOLID 的方法,并且 AdRepository<TEntity>
有类似
的支持接口
public class AdRepository<TEntity> : IAdRepository<TEntity>
where TEntity : AdBase {
public AdRepository(ApplicationDbContext dbContext) {
//...
}
}
假设...
public class AdPersister<TEntity> : IAdPersister<TEntity>
where TEntity : AdBase {
public AdPersister(IAdRepository<TEntity> adRepository, IAdImagePersister imagePersister) {
//...
}
//...
}
然后创建开放通用依赖项的方法如下所示
private static void RegisterServices(IKernel kernel) {
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
kernel.Bind<IAdImagePersister>().To<S3AdImagePersister>();
//Open generic bind for repository and ad persister
kernel.Bind(typeof(IAdRepository<>)).To(typeof(AdRepository<>));
kernel.Bind(typeof(IAdPersister<>)).To(typeof(AdPersister<>));
}
现在,只要需要 persister,您就可以简单地将封闭类型注入
ctor(IAdPersister<Foo> fooPersister)
并且必要的依赖项将由容器解析和注入。
真的不需要那个静态工厂。
更新
根据评论,我仍然建议不要使用静态工厂。
如果您想将实现细节保留在您的库内部,那么将工厂设为一个实例 class
public class AdPersisterFactory<TEntity> : IAdPersisterFactory<TEntity>
where TEntity : AdBase {
private readonly ApplicationDbContext dbContext;
public AdPersisterFactory(ApplicationDbContext dbContext) {
this.dbContext = dbContext;
}
public IAdPersister<TEntity> Create() {
AdRepository<TEntity> adRepository = new AdRepository<TEntity>(dbContext);
IAdImagePersister s3AdImagePersister = new S3AdImagePersister();
AdPersister<TEntity> adPersister = new AdPersister<TEntity>(adRepository, s3AdImagePersister);
return adPersister;
}
}
可以在您的组合根目录中注册为开放通用。
private static void RegisterServices(IKernel kernel) {
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
kernel.Bind(typeof(IAdPersisterFactory<>)).To(typeof(AdPersisterFactory<>));
}
并使用
ctor(IAdPersisterFactory<Foo> fooPersisterFactory) {
IAdPersister<Foo> fooPersister = fooPersisterFactory.Create();
//...
}
我有一个工厂来创建通用服务:
public static class AdPersisterFactory<TEntity>
where TEntity : AdBase
{
public static AdPersister<TEntity> Create(ApplicationDbContext dbContext)
{
AdRepository<TEntity> adRepository = new AdRepository<TEntity>(dbContext);
IAdImagePersister s3AdImagePersister = new S3AdImagePersister();
AdPersister<TEntity> adPersister = new AdPersister<TEntity>(adRepository, s3AdImagePersister);
return adPersister;
}
}
我想使用 ninject(版本 3),如何将 IAdPersister
绑定到上述工厂创建的实例...这是我的 DI 代码:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
// I have tried the following which does not compile
// kernel.Bind(typeof(IAdPersister<>)).ToMethod(ctx => AdPersisterFactory<>.Create(new ApplicationDbContext()));
}
这是针对 ASp.NET MVC 应用程序的,因此理想情况下我不想使用新的 ApplicationDbContext
,而是使用 RequestScope
中存在的相同 ApplicationDbContext
。
我也看到了Ninject.Extensions.Factory但是我不确定how/if我可以在这种情况下使用它
如果您愿意重构为更 SOLID 的方法,并且 AdRepository<TEntity>
有类似
public class AdRepository<TEntity> : IAdRepository<TEntity>
where TEntity : AdBase {
public AdRepository(ApplicationDbContext dbContext) {
//...
}
}
假设...
public class AdPersister<TEntity> : IAdPersister<TEntity>
where TEntity : AdBase {
public AdPersister(IAdRepository<TEntity> adRepository, IAdImagePersister imagePersister) {
//...
}
//...
}
然后创建开放通用依赖项的方法如下所示
private static void RegisterServices(IKernel kernel) {
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
kernel.Bind<IAdImagePersister>().To<S3AdImagePersister>();
//Open generic bind for repository and ad persister
kernel.Bind(typeof(IAdRepository<>)).To(typeof(AdRepository<>));
kernel.Bind(typeof(IAdPersister<>)).To(typeof(AdPersister<>));
}
现在,只要需要 persister,您就可以简单地将封闭类型注入
ctor(IAdPersister<Foo> fooPersister)
并且必要的依赖项将由容器解析和注入。
真的不需要那个静态工厂。
更新
根据评论,我仍然建议不要使用静态工厂。
如果您想将实现细节保留在您的库内部,那么将工厂设为一个实例 class
public class AdPersisterFactory<TEntity> : IAdPersisterFactory<TEntity>
where TEntity : AdBase {
private readonly ApplicationDbContext dbContext;
public AdPersisterFactory(ApplicationDbContext dbContext) {
this.dbContext = dbContext;
}
public IAdPersister<TEntity> Create() {
AdRepository<TEntity> adRepository = new AdRepository<TEntity>(dbContext);
IAdImagePersister s3AdImagePersister = new S3AdImagePersister();
AdPersister<TEntity> adPersister = new AdPersister<TEntity>(adRepository, s3AdImagePersister);
return adPersister;
}
}
可以在您的组合根目录中注册为开放通用。
private static void RegisterServices(IKernel kernel) {
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
kernel.Bind(typeof(IAdPersisterFactory<>)).To(typeof(AdPersisterFactory<>));
}
并使用
ctor(IAdPersisterFactory<Foo> fooPersisterFactory) {
IAdPersister<Foo> fooPersister = fooPersisterFactory.Create();
//...
}