实例化特定类型的存储库是否正常

本文关键字:是否 存储 类型 实例化 | 更新日期: 2023-09-27 17:57:28

假设我有一个LolCats.Data项目,它包含各种实现如下接口的存储库:

public interface ILolCatRepository
{
    ILolCat Get(Guid id);
    void Save(ILolCat lolcat);
    List<ILolCat> GetAll();
}

在Get(id)方法中,我需要返回一个实现接口ILolCat的类型的新实例。但与此同时,我不想通过返回新的LolCat()来引用类型LolCat。

有什么办法让ninject为我创建LolCat类型的实例吗?或者这里最好的模式是什么?不确定我是不是想得太多了。也许存储库实例化LolCat并不重要,因为它无论如何都会返回接口?另一方面,如果我以某种方式使用Ninject,这意味着存储库引用了一个特定的IOC容器解决方案,这可能很糟糕。

实例化特定类型的存储库是否正常

您有几个选项可以避免执行new LocalCat():

选项#1

public class LolCatRepository : ILolCatRepository
{
 public ILolCat Get(Guid id)
 {
   return NinjectHelper.Resolve<ILolCat>();
 }
}

Ninject的设置如下:

Bind<ILolCat>().To<LolCat>();

帮助者将类似于:

public static class NinjectHelper
{
 public static T Resolve<T>()
 {
  IKernel kernel = new StandardKernel();
  kernel.Load(Assembly.GetExecutingAssembly());
  return kernel.Get<T>();
 }
}

选项#2更干净,使用构造函数注入:

public class LolCatRepository : ILolCatRepository
{
 public List<ILocalCat> _localCats;
 // ninject will inject this list due to the chain of dependency.
 // if it fails, then go with option #1.
 public LolCatRepository(List<ILocalCat> localCats)
 {
  this._localCats = localCats;
 }
 public ILolCat Get(Guid id)
 {
   return this._localCats.FirstOrDefault(lc => lc.Id == id);
 }
 // similarly GetAll
}

当然,您可以让ninject将Func<ILolCat> factory注入到ILolCatRepository的构造函数中。

或者你也可以为工厂创建一个接口,并使用像一样的NinjectFactory扩展

IBindingRoot.Bind<ILolCatFactory>().ToFactory();

附带说明一下,为什么要为每种类型实现一个新的存储库?为什么不只是使用这样的界面:

public interface IRepository 
{
    T Get<T>(Guid id);
    void Save<T>(T entity);
    ....
}