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

时间:2013-03-26 15:13:29

标签: c# generics repository-pattern unit-of-work

我正在关注与Repository Pattern模式相结合的Unit 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>();
  }
}

我的问题出现在我正在关注的教程中,Dictionairy<Type, object>类中只有RepositoryProvider并且似​​乎没有填充它,因此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>吗?这看起来很脏。我正在疯狂地试图解决这个问题!

提前致谢。

3 个答案:

答案 0 :(得分:0)

我从一开始就看到你的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> - 而且,它很大程度上取决于你正在使用的工厂的特定发现实现。

答案 1 :(得分:0)

如果您还没有找到答案,我会按照教程进行操作(教程示例)。如果您确定已正确实施,请注意这一点,

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

希望有所帮助

答案 2 :(得分:0)

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

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