【发布时间】:2012-06-19 12:02:17
【问题描述】:
我正在寻找避免过度使用构造函数注入的最佳实践。例如,我有会议实体,它有几个子实体,如下所示:
- 会议
- 会议联系人
- 会议与会者
- 会议类型
- 地址
- 会议公司
- 会议记录
MeetingService 类如下所示:
public class MeetingService
{
private readonly IMeetingContactRepository _meetingContactRepository;
private readonly IMeetingAttendeeRepository _meetingAttendeeRepository;
private readonly IMeetingTypeRepository _meetingTypeRepository;
private readonly IAddressRepository _addressRepository;
private readonly IMeetingCompanyRepository _meetingCompanyRepository;
private readonly IMeetingNoteRepository _meetingNoteRepository;
private readonly IMeetingRepositoy _meetingReposity;
public MeetingService(IMeetingRepositoy meetingReposity, IMeetingContactRepository meetingContactRepository, IMeetingAttendeeRepository meetingAttendeeRepository,
IMeetingTypeRepository meetingTypeRepository, IAddressRepository addressRepository,
IMeetingCompanyRepository meetingCompanyRepository, IMeetingNoteRepository meetingNoteRepository)
{
_meetingReposity = meetingReposity;
_meetingContactRepository = meetingContactRepository;
_meetingAttendeeRepository = meetingAttendeeRepository;
_meetingTypeRepository = meetingTypeRepository;
_addressRepository = addressRepository;
_meetingCompanyRepository = meetingCompanyRepository;
_meetingNoteRepository = meetingNoteRepository;
}
public void SaveMeeting(Meeting meeting)
{
meetingReposity.Save();
if(Condition1())
_meetingContactRepository.Save();
if(Condition2())
_meetingAttendeeRepository.Save();
if(Condition3())
_meetingTypeRepository.Save();
if(Condition4())
_addressRepository.Save();
if(Condition5())
_meetingCompanyRepository.Save();
if(Condition6())
_meetingNoteRepository.Save();
}
//... other methods
}
这里只是七个依赖项,但真正的代码包含更多。我使用了"Dependency Injection Constructor Madness" 中描述的不同技术,但我还没有找到如何处理存储库依赖项。
有什么方法可以减少依赖的数量并保持代码可测试?
【问题讨论】:
-
创建一个 MeetingConfiguration 类,其中构造函数为您“放牧猫”。然后,您可以将 MeetingConfiguration 类传递给您正在初始化的任何内容。你不会解决有多个重载的问题,但至少所有的重载都在一个地方。
-
如果你真的写信给
MeetingService中的所有这些存储库,它一定做了很多。将MeetingService拆分为仅共享密钥的其他服务怎么样?我的意思是,你在这里的工作单位是什么?如果会议在meetingReposity.Save();之后完成,则触发一个事件并让所有其他人订阅。 -
我认为@dtryon 的建议要好得多。我不喜欢创建一个“配置”类只是为了隐藏你实际上有很多依赖项的想法。这只会使代码变得不那么清晰,但组织起来并没有更好。
-
也同意@dtryon(发布答案!)如此大量的构造函数参数通常是一个明确的迹象,表明一个类做的太多并违反了 SRP
-
我认为存储库的存储库是有序的……实际上,您可以使用 MEF 和 compose。
标签: c# .net unit-testing dependency-injection repository-pattern