如何将存储库注入UnitOfWork?

时间:2012-08-03 07:48:04

标签: dependency-injection repository unit-of-work

我已经实现了我的UnitOfWork,以便它保留对所有存储库的引用。

public interface IUnitOfWork
{
   void Commit();
   void RollBack();
}

public interface IMyUnitOfWork : IUnitOfWork
{
   IFooRepository Foos { get; }
   IBarRepository Bars { get; }
   // Other repositories ...
}

请注意,存储库实现了一种通用类型的存储库接口。

public interface IFooRepository : IRepository<Entities.Foo>
{
    // FooRepository specific methods goes here.
}

public interface IRepository<T> : IRepository
    where T : class
{
}

现在我如何将这些存储库注入我的UnitOfWork。当然我希望它们具有延迟加载行为。例如:

public class ConcreteUnitOfWork : IMyUnitOfWork
{
   private readonly IUnityContainer unityContainer;
   private IFooRepository fooRepository;

   public ConcreteUnitOfWork(IUnityContainer unityContainer)
   {
      this.repositoryFactory = repositoryFactory;
   }

   public IFooRepository Foos
   {
      get 
      { 
         return this.fooRepository ?? 
            (this.fooRepository = unityContainer.Resolve<IFooRepository>()); 
      }
   }
}

我知道将Unity容器传递给UnitOfWork是不正确的,但是你会提供什么模式来解决这个问题?

您可能会提到我不应该在UnitOfWork中保留存储库引用,但请假设一个需要多个存储库的服务类。通过这种设计,我可以将UnitOfWork作为构造函数参数(构造函数注入)传递给服务类,但是如果我没有在UnitOfWork中保留存储库引用,我将不得不将所有需要的存储库作为构造函数参数传递,你就知道了什么它导致了。

- 更新 -

如果我绝对错误,请告诉我,我不应该在UnitOfWork中编写存储库。那么请在这里给我一个关于“Constructor Over-injection”的解决方案。

- UPDATE2 -

似乎从UnitOfWork编写(引用)存储库会破坏Open / Closed原则,因为我们需要在添加新存储库时添加新的属性来更改UnitOfWork类。

如果是的话我应该考虑重构。你能给我一些想法吗?

1 个答案:

答案 0 :(得分:5)

似乎当前的设计方案将多个职责混合到IMyUnitOfWork界面中。您说这是因为否则服务类可能需要独立地获取每个存储库。我假设你的意思是这样的:

public MyService(
   IUnitOfWork uow,
   IFooRepository fooRepository,
   IBarRepository barRepository)

在我看来,这是一个更简单,更清洁的设计。

但那么Constructor Over-injection呢?

嗯,那就是......但事实是,这与您现在使用ConcreteUnitOfWork实现的问题完全相同。你还没有完全解决构造函数的过度注入气味 - 你刚刚把它移到了另一个类。

实际上,通过将其移动到ConcreteUnitOfWork,你已经使更多难以处理这种情况。因为ConcreteUnitOfWork是一个纯粹的基础结构类(或支持类,如果你愿意),它没有任何业务上下文,所以很难建议一种解决构造函数注入过量气味的方法。

另一方面,给定的服务(或者可能是控制器)往往更专业,并且具有业务上下文的知识,因此它不需要每个存储库它的工作 - 如果确实如此,它可能会尝试做太多。

这样的特定业务组件最好是refactored to a Facade Service