请参阅下面的代码,我从Jimmy Bogards Wicked域名模型中获取:
public class OfferAssignmentService
{
private readonly IMemberRepository _memberRepository;
private readonly IOfferTypeRepository _offerTypeRepository;
private readonly IOfferValueCalculator _offerValueCalculator;
private readonly IOfferRepository _offerRepository;
public OfferAssignmentService(
IMemberRepository memberRepository,
IOfferTypeRepository offerTypeRepository,
IOfferValueCalculator offerValueCalculator,
IOfferRepository offerRepository
)
{
_memberRepository = memberRepository;
_offerTypeRepository = offerTypeRepository;
_offerValueCalculator = offerValueCalculator;
_offerRepository = offerRepository;
}
public void AssignOffer(Guid memberId, Guid offerTypeId)
{
// Retreive
var member = _memberRepository.GetById(memberId);
var offerType = _offerTypeRepository.GetById(offerTypeId);
// Delegate to business objects
var offer = member.AssignOffer(offerType, _offerValueCalculator);
// Save
_offerRepository.Save(offer);
}
}
为什么将存储库注入服务?假设我有一个应用程序,它有四个客户端(移动; WPF; MVC4; Win Forms),然后所有这些客户端必须创建这些存储库的实例并将它们传递给服务。为什么服务不仅仅是在一个地方创建它们。
我显然在这里遗漏了一些东西。
更新
如果我在Serivce层中创建存储库,则它们是四个依赖关系,即一个用于_memberRepository;一个用于_offerTypeRepository;一个用于_offerValueCalculator,另一个用于_offerRepository。如果我在四个客户端中创建所有这些实例,那么我将创建16个依赖项,即4 * 4。我意识到我在这里缺少一些基本的东西。
答案 0 :(得分:1)
您的个人客户不应负责了解如何详细配置这些依赖项。如果您的客户端依赖OfferAssignmentService
,那么它不应该负责了解该类的所有依赖关系,例如存储库,以及这些存储库的依赖关系等。如果那在使用OfferAssignmentService
的地方复制代码然后可以改进。
理想情况下,会有一个配置类作为此服务层的组合根,客户端将引用该类并使用它来配置服务的依赖关系。具体情况取决于您使用的容器。例如,使用Windsor,我会创建一个继承自AbstractFacility
的类。我的客户只会这样做:
container.AddFacility<OfferAssignmentServiceFacility>();
该工具将处理使用我的容器配置所有依赖项。
在Unity中,它将是一个继承自UnityContainerExtension
的类,与Windsor非常相似,你会做的
container.AddNewExtension<OfferAssignmentServiceExtension>();
它们的共同点是它们将容器传递给配置类,允许该类使用所需的依赖项来配置容器。
如果您不介意将服务紧密耦合到容器框架,则可以将该代码直接放在服务库中。我喜欢让我的库与容器无关(他们不需要一个特定品牌的DI容器来工作。)所以我将把设施或扩展放在一个单独的库中。