如何实现通用的RepositoryFactory?

时间:2010-12-21 15:46:36

标签: c# design-patterns entity-framework-4 repository-pattern factory-pattern

我正在尝试实现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;
    }
}

RepositoryFactory由我的工作单元实现

使用
public interface IUnitOfWork : IDisposable
{
    IRepository<T> RepositoryOf<T>() where T : class;
    void Commit();
}

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

我需要一种方法来询问任何类型的IRepository,所以我的安装程序代码会这样做......

// Windsor Container
container.Register(
    Component.For<IWindsorContainer>()
        .Named("Container")
        .Instance(container)
    );

这似乎与IoC的整个概念背道而驰,但是那么要求存储库的整个想法无论如何都会这样做。

修改(回复miensol的答案)

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

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

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

所以,我有点困惑!

1 个答案:

答案 0 :(得分:5)

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

public IRepository<T> RepositoryOf<T>() where T : class
{
  return ServiceLocator.Current.GetInstance<IRepository<T>>();
}

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

container.Register(
  Component.For(typeof(IRepository<>)).ImplementedBy(typeof(GenericRepositoryImplementation<>))
);

并将它们注入您的对象:

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

  public ClassThatRequiresSomeRepos(IRepository<OneEntity> oneEntityRepository, IRepository<TwoEntity> twoEntityRepository)
  {
    _repoOne = oneEntityRepository;
    _repoTwo = twoEntityRepository;
  }
}