如何实现一个通用的RepositoryFactory? [英] How to implement a generic RepositoryFactory?

查看:156
本文介绍了如何实现一个通用的RepositoryFactory?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一个通用存储库。这是我到目前为止...

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

public class EntityFrameworkRepositoryFactory:IRepositoryFactory
{
private readonly IWindsorContainer _container;

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

public IRepository< T> RepositoryOf< T>()其中T:class
{
var repository = _container.Resolve< IRepository< T>
返回存储库;
}
}

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

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

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



我需要一种方式来请求任何类型的存储库,所以我的安装程序代码这样做...


$ (
Component.For< IWindsorContainer>()
.Named(Container)
.Instance(container)
);

这似乎只是反对IoC的整体概念,但也许是要求



编辑(作为回复 miensol 的答案)



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



  //通用存储库
container.Register(
Component.For(typeof(IRepository&)))
.ImplementedBy(typeof(EntityFrameworkRepository&))
.ServiceOverrides(
ServiceOverride.ForKey(objectContext)。Eq(ObjectContext))
);

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



所以,我有点困惑!

解决方案

我不完全确定为什么在使用IoC框架时需要 IRepositoryFactory 。然而,依赖于分散在代码库中的特定IoC容器实现通常不是一个好主意。大部分时候,当我真的找不到一个方法使容器注入依赖对象我使用服务定位器模式,这里你可以找到一个常用的.net实现。那么你的工厂方法将如下所示:

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

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

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

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

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

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


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

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?

I needed a way of asking for an IRepository of any type, so my installer code does this ...

// 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.

Edit (As reply to miensol's answer)

I am already using Windsor to create the repositories for me with the following code in my installer ...

// 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. 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. 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. However having dependencies to specific IoC container implementations scattered though the code base is generally not a good idea. 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. 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:

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

这篇关于如何实现一个通用的RepositoryFactory?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆