如何将存储库注入UnitOfWork? [英] How can I inject the Repositories to the UnitOfWork?

查看:153
本文介绍了如何将存储库注入UnitOfWork?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've implemented my UnitOfWork so that it keeps references to all repositories.

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中。当然,我希望它们具有延迟加载行为。例如:

Now how can I inject these repository to my UnitOfWork. Of course I want them with a lazy loading behavior. For example:

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是不正确的,但是您将提供什么模式来解决此问题?

I know passing the Unity container to the UnitOfWork is incorrect but what pattern would you offer to solve this issue?

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

You may mention that I shouldn't keep the repository references in the UnitOfWork but please suppose a service class which needs several repositories. With this design I can just pass the UnitOfWork as the constructor parameter (Constructor Injection) to the service class, but if I didn't keep the repository references in UnitOfWork, I would have to pass all needed repositories as constructor parameters and you know what it leads to.

-更新-

请告诉我是否绝对错误,并且我绝不应该在UnitOfWork中编写存储库。然后,请在此处为我提供有关构造函数过度注入的解决方案。

Please let me know if I'm absolutely wrong and I should never compose the repositories in UnitOfWork. Then please give me a solution about "Constructor Over-injection" here.

-UPDATE2-

似乎(参照)由UnitOfWork组成的存储库违反了打开/关闭原则,因为当我们添加新的存储库(添加新的属性)时,我们需要更改UnitOfWork类。

It seems that composing (referencing to) the repositories from UnitOfWork breaks the Open/Closed principle as we need to change the UnitOfWork class when we add a new repository (add a new property).

如果正确,那么我应该考虑进行重构。

If it's right then I should consider a refactoring. Would you please give me some ideas?

推荐答案

似乎当前的设计提案在IMyUnitOfWork接口中混合了多个职责。您之所以这么说是因为,否则服务类可能需要独立获取每个存储库。我假设您的意思是这样的:

It seems as though the current design proposal mixes more than one responsibility into the IMyUnitOfWork interface. You say that this is because otherwise a service class might need to take each Repository independently. I'm assuming you mean something like this:

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

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

This seems to me to be a much simpler and cleaner design.

但是构造函数注入过多呢?

But then what about Constructor Over-injection?

嗯,那是...但是事情是这与您的ConcreteUnitOfWork实现完全相同。您根本还没有解决构造函数过度注入的气味-您只是将其移至另一个类。

Well, there's that... but the thing is that this is exactly the same problem you now have with your ConcreteUnitOfWork implementation. You haven't solved the Constructor Over-injection smell at all - you've just moved it to another class.

实际上,通过将其移至您制作的ConcreteUnitOfWork more 很难处理这种情况。因为ConcreteUnitOfWork是一个纯基础结构类(或者,如果有的话,它是一个支持类),它没有任何业务上下文,所以在这里很难提出一种解决构造函数注入过多气味的方法。

Actually, by moving it to ConcreteUnitOfWork you've made it more difficult to deal with the situation. Because ConcreteUnitOfWork is a pure infrastructure class (or a support class, if you will) it doesn't have any business context, so it's really hard to suggest a way resolve the Constructor Over-injection smell here.

另一方面,给定的服务(或控制器)可能会更加专门化并且具有业务背景知识,因此不需要每一个存储库以完成其工作-否则,它可能会尝试做太多事情。

On the other hand, a given Service (or perhaps a Controller) would tend to be more specialized and have knowledge of the business context, so it wouldn't need every repository in order to do its job - or if it does, it probably attempts to do too much.

这样的特定业务组件最好是重构为外观服务

Such a specific business component can better be refactored to a Facade Service.

这篇关于如何将存储库注入UnitOfWork?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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