如何实现通用的RepositoryFactory?

Ant*_*ott 8 c# design-patterns repository-pattern factory-pattern entity-framework-4

我正在尝试实现Generic Repository.这是我到目前为止所得到的......

public interface IRepositoryFactory
{
    IRepository<T> RepositoryOf<T>() where T : class;
}

public class EntityFrameworkRepositoryFactory : IRepositoryFactory
{
    private readonly IWindsorContainer _container;

    public EntityFrameworkRepositoryFactory(IWindsorContainer container)
    {
        _container = container;
    }

    public IRepository<T> RepositoryOf<T>() where T : class
    {
        var repository = _container.Resolve<IRepository<T>>();
        return repository;
    }
}
Run Code Online (Sandbox Code Playgroud)

RepositoryFactory由我的工作单元实现使用

public interface IUnitOfWork : IDisposable
{
    IRepository<T> RepositoryOf<T>() where T : class;
    void Commit();
}
Run Code Online (Sandbox Code Playgroud)

无论如何,我想问的问题是,RepositoryFactory实现依赖于IWindsorContainer是否正确?

我需要一种方法来询问任何类型的IRepository,所以我的安装程序代码执行此操作...

// Windsor Container
container.Register(
    Component.For<IWindsorContainer>()
        .Named("Container")
        .Instance(container)
    );
Run Code Online (Sandbox Code Playgroud)

这似乎与IoC的整个概念背道而驰,但随后可能要求存储库的整个想法无论如何都会这样做.

编辑(回复miensol的回答)

我已经使用Windsor在我的安装程序中使用以下代码为我创建存储库...

// Generic Repository
container.Register(
    Component.For(typeof (IRepository<>))
        .ImplementedBy(typeof (EntityFrameworkRepository<>))
        .ServiceOverrides(
            ServiceOverride.ForKey("objectContext").Eq("ObjectContext"))
    );
Run Code Online (Sandbox Code Playgroud)

我过去曾使用过ServiceLocator来实现我想要的,但是已经读到它有点像反模式.所以试图避免使用它.虽然我不得不承认我不知道为什么,因为我所做的事情似乎也错了,因为我一定会使用Castle Windsor作为我的IoC/DI框架.服务定位器旨在与框架无关.

所以,我有点困惑!

mie*_*sol 5

IRepositoryFactory当您使用IoC框架时,我不完全确定您为什么需要 .但是,通过代码库分散对特定IoC容器实现的依赖性通常不是一个好主意.大多数时候,当我真的找不到让容器为我的对象注入依赖项的方法时,我使用Service Locator Pattern,在这里你可以找到一个常用的.net实现.那么你的工厂方法看起来像这样:

public IRepository<T> RepositoryOf<T>() where T : class
{
  return ServiceLocator.Current.GetInstance<IRepository<T>>();
}
Run Code Online (Sandbox Code Playgroud)

尽管如此,您似乎可以让Windsor为您创建通用存储库:

container.Register(
  Component.For(typeof(IRepository<>)).ImplementedBy(typeof(GenericRepositoryImplementation<>))
);
Run Code Online (Sandbox Code Playgroud)

并将它们注入您的对象,如下所示:

public class ClassThatRequiresSomeRepos
{
  IRepository<OneEntity> repoOne;
  IRepository<TwoEntity> repoTwo;

  public ClassThatRequiresSomeRepos(IRepository<OneEntity> oneEntityRepository, IRepository<TwoEntity> twoEntityRepository)
  {
    _repoOne = oneEntityRepository;
    _repoTwo = twoEntityRepository;
  }
} 
Run Code Online (Sandbox Code Playgroud)