如何将存储库注入UnitOfWork? [英] How can I inject the Repositories to the 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屋!