业务层和表示层之间的依赖注入

Posted

技术标签:

【中文标题】业务层和表示层之间的依赖注入【英文标题】:Dependency injection between business layer and presentation layer 【发布时间】:2021-11-06 23:27:39 【问题描述】:

我正在尝试在我的软件中遵循干净的架构。我已经实现了 3 层:数据层、业务层和表示层。

据我了解,依赖性会像 P->B->D 一样从外到内。

但我的问题是我应该将单例数据层执行器注入到演示文稿中吗?这不是打破这个逻辑吗?

或者没有 DI,只在我认为会产生紧密耦合的层之间创建抽象。

因此,从业务层内部引用一些数据层依赖关系 - 这不是使各层紧密耦合吗?

public class ViewModel<T> extends GenericRouter 
    IPresentation ip = new BusinessUseCaseImpl();

public abstract class BusinessUseCase<T extends HashMap> implements IPresentation<T> 

UserRepository urepo = new UserRepository();

【问题讨论】:

【参考方案1】:

这取决于您所说的“紧密耦合”是什么意思。 遵循 3 层架构,数据层依赖于业务层,业务层依赖于表现层。

您始终可以在接口上定义依赖注入,而不是注入具体的类。这样一来,只要按照约定的接口,就可以随时切换实现。

但是,我的经验告诉我,对于基本和常规的 3 层架构,您很少或从不这样做。你总是有一个单一的服务和一个单一的存储库/DAO 实现,所以为它们中的每一个都有一个接口是多余的和无用的。

我认为,当您使用 3 层架构时,最重要的是永远不要绕过层。例子:

    永远不要让表示层直接依赖于数据层。始终通过业务层。 层之间的关系应始终为 1:1。这意味着您永远不应该让 Controller 调用与另一个 Controller 关联的 Service。

不遵守这些规则肯定会使您的代码难以阅读和理解。当然,对于每条规则,都有一个例外,但请尽量遵守它们。

【讨论】:

是的,现在presentationlayer实例化了一个抽象类(实现pressntationlayer的接口),它位于业务层内部,错了吗? (我的问题数据层有一个模块依赖回到业务层?所以数据层将数据推回业务,所以它是紧耦合的?) 公共类 ViewModel 扩展 GenericRouter IPresentation ip = new BusinessUseCaseImpl();有错吗? 嗯,在一个利用依赖注入的项目中,任何应该是 bean 的类的实例化确实是错误的。您应该只声​​明依赖项和框架(无论是 JakartaEE、Spring 还是其他)将负责注入。 关于“我的问题数据层有一个模块依赖回到业务层?所以数据层将数据推回业务,所以它是紧耦合的?”答案是肯定的,不应该是这样。业务层应该有数据层作为依赖,但数据层不应该有对业务层的依​​赖。事实上,这基本上是一种循环依赖,在 Spring 等框架中是不允许的(如果您想了解更多信息,请baeldung.com/circular-dependencies-in-spring)。 好的,所以没有DI,我认为层之间的关系可以通过接口和抽象类来建立。?请检查我在 viewmodels&businesslayer 类中添加了一些具体的类 instatiasions 的问题。 viewmodel 创建一个业务接口并调用其方法,然后业务层再次调用自身内部的数据层。这是手动依赖注入。但我认为这是真的。我很快就会把它换成匕首【参考方案2】:

在干净的架构中,内层是逻辑,而不是基础设施。

当业务层实例化数据层时,它会注入它需要的任何基础设施依赖项。

类似地,当表示层实例化业务层时,它会传入它需要的任何基础设施依赖项。这就是业务层获取传递给数据层所需的基础设施的方式。

最初,当应用程序/系统实例化表示层时,它会传入它需要的基础设施。谦虚的对象模式应该用于实现这些依赖关系,因为它们是系统的唯一部分,不能独立于基础设施进行测试。

【讨论】:

以上是关于业务层和表示层之间的依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

简单使用Moq框架

spring的注入依赖

spring 的依赖注入

04 Spring的依赖注入

依赖注入的实现方式:设值注入和构造方法注入

asp.net core自定义依赖注入容器,替换自带容器