c# - 构造函数注入(inject)过度使用

标签 c# .net unit-testing dependency-injection repository-pattern

我正在寻找避免过度使用构造函数注入(inject)的最佳实践。例如,我有 Meeting 实体,它有几个子实体,如下所示:

  • session
    1. session 联系人
    2. 与会者
    3. session 类型
    4. 地址
    5. session 公司
    6. session 记录

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" 中描述的不同技术但我还没有找到如何处理存储库依赖项。

有什么方法可以减少依赖项的数量并保持代码的可测试性?

最佳答案

构造函数过度使用只是一个症状 - 看起来你正在接近 unit of work通过拥有一个了解消息持久性的各种元素并将它们插入整体保存的“主”类。

缺点是每个存储库都通过公开一个专用的Save 方法来传达其与其他存储库的独立性;但是,这是不正确的,因为 SaveMeeting 明确指出存储库不是独立的。

我建议确定或创建存储库消费的类型;这集中了您的更改,并允许您从一个地方保存它们。示例包括 DataContext (LINQ to SQL) , ISession (NHibernate) , 和 ObjectContext (Entity Framework) .

您可以在我之前的回答中找到有关存储库如何工作的更多信息:

Advantage of creating a generic repository vs. specific repository for each object?

拥有存储库后,您将确定它们将在其中运行的上下文。这通常映射到单个 Web 请求:在请求开始时创建公共(public)工作单元的实例并将其传递给所有存储库。在请求结束时,保存工作单元中的更改,让存储库无需担心访问哪些数据。

这巧妙地将所有内容捕获并保存为一个单元。这与源代码控制系统的工作副本非常相似:将系统的当前状态拉入本地上下文,使用它,并在完成后保存更改。您不会单独保存每个文件 - 您可以将它们同时保存为一个独立的修订版。

关于c# - 构造函数注入(inject)过度使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11067241/

相关文章:

c# - 将对象转换为具有指定区域性的字符串

c# - Lambda 表达式的代码覆盖率

c# - Razor 代码块可以输出到 View 吗?

c# - 固定长度的 Int 混淆器。有谁知道如何做到这一点?

.net - .NET 的智能卡身份验证

javascript - 如何使用 sinonjs 和 jquery 监 window 口调整大小事件?

visual-studio - 在 Visual Studio 2019 中未发现单元测试

c# - 上传图像并获取其字节

c# - 在 ASP.Net 中使用的最佳 session 状态模式是什么,这样我的网站的 CPU 使用率就不会很高?

.net - SQL Server CE数据库大小问题