如何实现一个通用的RepositoryFactory?

发布于 2024-10-08 19:11:57 字数 1756 浏览 3 评论 0 原文

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

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

无论如何,我想问的问题是 RepositoryFactory 实现依赖于 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 框架。服务定位器与框架无关。

所以,我有点困惑!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情深已缘浅 2024-10-15 19:11:57

我不完全确定为什么在使用 IoC 框架时需要 IRepositoryFactory。然而,对分散在代码库中的特定 IoC 容器实现的依赖通常不是一个好主意。大多数时候,当我确实找不到方法让容器将依赖项注入到我的对象时,我使用服务定位器模式,在这里您可以找到 .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;
  }
} 

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;
  }
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文