UnitOfWork作为存储库的容器

时间:2013-03-14 13:35:13

标签: asp.net-mvc entity-framework architecture unit-of-work repository

我有一个看起来像这样的解决方案:

Project1< - >共享项目< - > Project2的

共享项目不是独立的,它通过服务层向其他项目公开它的功能,该服务层接受由其他两个项目注入到构造函数中的IUnitOfWork:

public SharedService (IUnitOfWork unitOfWork)
{
   ... do stuff ...
}

我遇到的问题是Project1和Project2有一组重叠但不同的存储库:

Project1: SharedRepository,RepositoryA,RepositoryB ...

Project2: SharedRepository,RepositoryX,RepositoryY ...

我一直在看implementations of Unit Of Work它在哪里扮演存储库的容器 - 你绕过UoW然后通过暴露它们的公共属性到达存储库:

unitOfWork.SharedRepository.GetSomething();

这种方法的结果是你最终得到了一个工作单元的界面,如下所示:

public interface IUnitOfWork
{
    ISharedRepository SharedRepository();
    IRepositoryA RepositoryA();
    IRepositoryB RepositoryB();
    IRepositoryX RepositoryX();
    IRepositoryY RepositoryY();

    ... etc ...
}

这是我遇到麻烦的地方:IUnitOfWork接口现在强制Project1和Project2实现彼此的存储库。 因此,在我看来,使用工作单元作为存储库容器的方法可能是一个有缺陷的概念。

我想到了一些可能的选择:

1)将IUnitOfWork分为3个部分(IProject1UnitOfWork,IProject2UnitOfWork,ISharedUnitOfWork),然后让服务层接受ISharedUnitOfWork参数。看起来很乱,但它可能会奏效。

2)将UnitOfWork转换为类似于服务定位器的东西,在那里维护一组存储库,然后注册您需要的东西。然后,UoW的消费者会检索它需要的任何存储库。

3)将工作单元和存储库单独注入服务层构造函数:

public SharedService (IUnitOfWork unitOfWork, ISharedRepository repository)
{
   ... do stuff ...
}

你们怎么处理这样的情况?我倾向于选项#3。它需要传递更多东西,但替代方案看起来不那么优雅。

1 个答案:

答案 0 :(得分:2)

  

所以在我看来,使用工作单元作为一种方法   存储库的容器可能是一个有缺陷的概念。

对我来说也是如此。您的示例中的工作单元也是伪服务定位器(通常已被视为反模式),因此它违反了SRP。 UoW只是一个事务包装器,围绕您想要放置的任何用例,它不应该知道有关存储库或用例中的任何内容的任何信息。

请参阅德米特里的答案:How does unit of work class know which repository to call on commit?

所以,对我来说绝对是选择3。