【问题标题】:Inversion of Control and injection of data layer dependencies in the Business Layer业务层中控制反转和数据层依赖注入
【发布时间】:2025-12-31 04:30:07
【问题描述】:

我们正在.net/c# 中设计一个分层的业务应用程序,并且我们正在尝试尽可能多地遵循 SOLID 原则。可测试性在我们的项目中非常重要,为此我们使用 Moq。使用 moq,除其他外,我们正在模拟我们的实体框架上下文。

由于我们测试的主要目标是主要业务层 (BL) 逻辑,因此业务层类可以注入数据访问层 (DAL) 上下文来使用。请参见下面的示例。 负责加载数据的 BL 类的示例构造函数。该类为设置访问等注入依赖项。

    public LoadDataProcess(KonstruktEntities context, IDataLoadedChecker dataLoadedChecker, ILoadUserBudgetData dataLoader, ISetLineAccess setBudgetLineStatus, ILineAccessFilterHandler budgetDataLineStatusFilterHandler) 
    {
        _context = context;
        _dataLoadedchecker = dataLoadedChecker;
        _dataLoader = dataLoader;
        _setBudgetLineStatus = setBudgetLineStatus;
        _budgetDataLineStatusFilterHandler = budgetDataLineStatusFilterHandler;
    }

现在,还有其他 DAL 依赖项可以注入到我们的 BL 类中。由于这些对象是在服务层 (WCF) 中实例化的,因此我不喜欢可以注入 DAL 组件。

问题是,我们是否应该将 DAL 依赖项注入到 BL 类中?

【问题讨论】:

  • 如果您尝试将 SOLID 应用到您的业务层,请查看 thisthisthis 文章,因为它们可以在可维护性和灵活性方面产生巨大差异您的应用程序。
  • 会看看这些,谢谢。你觉得我问的这个问题怎么样?

标签: c# dependency-injection inversion-of-control solid-principles business-logic-layer


【解决方案1】:

由于您的 BL 依赖于抽象,因此您遵循依赖倒置原则 (DIP)。很明显,您的业务层需要与 DAL 进行通信;确实没有办法解决这个问题,但是由于您依赖于抽象而不是低级组件,所以这很好。

【讨论】:

  • 好的,为了进一步争取 DIP 奖牌,您认为有理由以任何方式包装“KonstruktEntities”类吗?它继承自 DbContext,它是一个 IObjectContextAdapter
  • 我看到的一个问题是,例如,在我的服务层中的 WCF 函数中,我需要直接注入 DAL 依赖项。感觉我不应该在服务层实例化任何 DAL 对象,但也许必须这样做?!
  • @JohanLarsson:你的所有组件都应该在你的Composition Root 中实例化,别无他处。让你的代码依赖于DbContext 总是违反 DIP,但这是你不能总是阻止的。您必须在某处查询数据库。
  • 是的,我知道很难做到完全稳定。我的组合根位于服务层中,它使用 IoC 容器,所以我想我当时做的事情“足够好”。感谢您的输入。最后一个问题,我应该实例化一次上下文并将相同的上下文注入所有依赖类吗?这样,同一个上下文对象就可以在整个图中重用
  • @JohanLarsson:100% 符合 SOLID 原则是不可能的。将它们应用在有意义的地方。关于注入DbContext,请阅读this q/a