工作单元模式——使用工厂获取存储库

本文关键字:获取 存储 工厂 单元 模式 工作 | 更新日期: 2023-09-27 18:06:01

我正在遵循Repository PatternUnit Of Work模式组合的教程。

我有:

interface IRepository<T> where T : class
{
  //...
}
class Repository<T> where T : class
{
  //Implemented methods 
}
interface IFooRepository
{
  IQueryable<Foo> GetFoos();
}
class FooRepository : Repository<Foo>, IFooRepository
{
  IQueryable<Foo> GetFoos() {}
}

以上基本代表了我的repositories。然后我有一个Uow类。

public class MyUow
{
  public void Commit() { }
  public IRepository<Bar> Bars { get { return GetStandardRepo<Bar>(); } }
  public IFooRepository Foos { get { return GetRepo<IFooRepository>(); } }
  private IRepository<T> GetStandardRepo()
  {
    return RepositoryProvider.GetRepoistoryForEntityType<T>();
  }
  private T GetRepo<T>()
  {
    return RepositoryProvider.GetRepository<T>();
  }
}

我的问题是我所遵循的教程只在RepositoryProvider类中实例化Dictionairy<Type, object>,并且似乎没有填充它,因此GetRepo<T>中使用的方法不起作用。

public virtual T GetRepository<T>(Func<DbContext, object> factory = null) where T : class
{
  //Look for T in the dictionairy by typeof(T)
  object repoObj;
  Repositories.TryGetValue(typeof(T), out repoObj);
  if (repoObj != null)
    return (T)repoObj;
  //Not found or a null value, make a new instance of the repository.
  return MakeRepository<T>(factory, Context);
}
private T MakeRepository<T>(Func<DbContext, object> factory, DbContext dbContext) where T : class
{
  var f = factory ?? _repositoryFactories.GetRepositoryFactory<T>();
  if (f == null)
    //Exception here because this is null
    throw new NotImplementedException("No factory for repository type");
  var repo = (T)f(dbContext);
  Repositories[typeof(T)] = repo;
  return repo;
}

我的问题本质上是实现这种模式的正确方法是什么,我在哪里出错了?我应该用已知存储库列表实例化Dictionairy<Type, Func<DbContext, object>吗?这看起来很脏。为了解决这个案子,我快把自己逼疯了!

工作单元模式——使用工厂获取存储库

我从一开始就看到的是你的Repository<T>没有实现IRepository<T>,所以它应该是这样的:

class Repository<T> : IRepository<T> where T : class
{
  //Implemented methods 
}

那么你的完全秘密的教程应该描述_repositoryFactories.GetRepositoryFactory<T>()如何发现你的IRepository<T>实实者FooRepository -也许它将是自动发现,也许你需要在某处注册一些东西。

接下来,我对你的具体教程和工厂等一无所知,但我想你可能需要使用GetRepo<Foo>而不是GetRepo<IFooRepository>,因为现在这个IFooRepository看起来毫无意义…或者你可能又在这个IFooRepository声明中遗漏了一些东西,它应该像interface IFooRepository : IRepository<Foo>一样-而且,它在很大程度上取决于你正在使用的工厂的特定发现实现。

如果您还没有找到答案,我遵循了教程并能够运行它(教程示例)。如果您确信您已经正确地实现了它,请注意这一点,

Repository Dictionary默认为null,并且在第一次请求时仅具有非标准repos(例如IFooRepository)的值。因此,如果您正在检查Repository Dictionary的调试值,并且还没有请求IFooRepository,那么您肯定不会在那里看到它。首先要有访问IFooRepository的代码,然后它会在提供程序类的MakeRepository方法中为它创建一个存储库。

希望有帮助

有一个助手类叫做RepositoryFactories.cs您需要将自定义存储库的条目添加到字典

{typeof(IFooRepository ), dbContext => new FooRepository (dbContext)}