简体   繁体   English

如何实现一个通用的RepositoryFactory?

[英]How to implement a generic RepositoryFactory?

I'm trying to implement a Generic Repository. 我正在尝试实现通用存储库。 This is what I've got so far ... 这是我到目前为止所得到的...

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;
    }
}

The RepositoryFactory is used by my unit of work implementation 我的工作单元实现使用RepositoryFactory

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

Anyway, the question I want to ask is whether having the RepositoryFactory implementation depend on IWindsorContainer is correct? 无论如何,我想问的问题是让RepositoryFactory实现依赖于IWindsorContainer是否正确?

I needed a way of asking for an IRepository of any type, so my installer code does this ... 我需要一种询问任何类型的IRepository的方式,因此我的安装程序代码会执行此操作...

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

Which just seems to go against the whole concept of IoC, but then maybe the whole idea of asking for a repository does that anyway. 这似乎与IoC的整个概念背道而驰,但是也许整个请求存储库的想法还是可以做到这一点。

Edit (As reply to miensol 's answer) 编辑(作为对miensol答案的答复)

I am already using Windsor to create the repositories for me with the following code in my installer ... 我已经在使用Windsor在安装程序中通过以下代码为我创建存储库...

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

I have used ServiceLocator in the past to achieve what I want, but have read that it's a bit of an anti-pattern. 我过去曾使用ServiceLocator来实现我想要的功能,但已阅读到它有点反模式。 So was trying to avoid using it. 因此试图避免使用它。 Although I have to admit that I'm not sure why, as what I've done also seems wrong as I am bound to using Castle Windsor as my IoC/DI framework. 尽管我不得不承认我不确定为什么,但是由于我一定要使用Castle Windsor作为IoC / DI框架,所以我所做的事情似乎也是错误的。 Service Locator is meant to be framework agnostic. 服务定位器旨在与框架无关。

So, I'm a bit confused! 所以,我有点困惑!

I'm not entirely sure why do you need IRepositoryFactory when you are using an IoC framework. 我不确定要使用IoC框架时为什么需要IRepositoryFactory However having dependencies to specific IoC container implementations scattered though the code base is generally not a good idea. 但是,通过代码库分散对特定IoC容器实现的依赖性通常不是一个好主意。 Most of the time when I really can't find a way to make the container inject dependencies to my objects I use Service Locator Pattern, here you can find a commonly used implementation for .net. 大多数时候,当我真的找不到使容器向我的对象注入依赖项的方法时,我在这里使用服务定位器模式, 在这里您可以找到.net的常用实现。 Then your factory method would look like this: 然后,您的工厂方法将如下所示:

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

Nevertheless it seems like you could just make Windsor create the generic repository for you anyways: 尽管如此,似乎您仍然可以使Windsor为您创建通用存储库:

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

and having them injected to your objects like so: 并将它们注入到您的对象中,如下所示:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM