三分钟搞懂依赖注入

简介: 三分钟搞懂依赖注入

应用程序通常是由多个组件构成的,组件和组件之间往往存在直接依赖的关系。这种依赖关系看似稳定,但是耦合度很高,如果其中一方不存在的话另一方也就无法工作,而且这种关系也增加了程序的维护成本和灵活性,同时也增加了单元测试的难度。那么,如何解决这个问题呢?这里我们就引入了依赖注入,下面我们通过一个例子来一步一步讲解。

例子很简单,下面这段代码将会向控制台输出一段话,这段话是从 Service 服务中获取的。

public class Demo
{
    public void ShowMessage()
    {
        DataService dataService = new DataService();
        string message = dataService.getMessage();
        Console.Write(message);
    }
}

在不使用依赖注入的情况下,我们通常就会上面这样编写代码,这段代码就像我前面所说的那样,如果 DataService 不存在或者 getMessage 不存在,那么这段代码是无法运行和编译的。下面我们就使用依赖注入的方式来解决这个问题。依赖注入的核心原则是高层不应直接依赖底层,两者均应依赖抽象或接口。根据这个核心原则我们分析前面的代码可知 ShowMessage (高层) 依赖于 DataService (底层),这时我们就需要将 DataService 替换成接口,高层将不会依赖于底层而是依赖于接口,此时高层只关心接口,而不去关心具体的实现,这就形成了 依赖倒置 。基于此,我们定义一个 IDataService 接口,然后 DataService 来实现这个接口。

public interface IDataService
{
    string getMessage();
}
public class DataService : IDataService
{
    public string getMessage()
    {
        return "Hi, I am Jack!";
    }
}

接下来我们在 Demo 中使用依赖注入:

public class Demo
{
    private readonly IDataService dataService;
    public Demo(IDataService dataService)
    {
        this.dataService = dataService;
    }
    public void ShowMessage()
    {
        string message = dataService.getMessage();
        Console.Write(message);
    }
}

我们在上面的代码中通过构造函数向 Demo 中注入了所需的依赖,这种通过构造方法注入依赖的方式称为 构造函数注入 ,是最常见的方式。通过构造函数获得需要依赖是类级别的全局变量,可以在整个类内部使用,并且构造函数注入遵循了显示依赖原则。除了构造函数注入外,还存在另外两种注入方式:属性注入和方法注入。属性注入是通过设置类属性来获取所需的依赖,属性注入虽然看起来和构造函数注入类似,但是它不需要显示的提供依赖,只要在已经实例化的对象上设置相应的属性即可,但是这样做会存在问题,因为依赖项属性设置的值不是强制性的,因此很容易忘记设置从而引发异常。方法注入则是通过在方法的参数中传入所需的依赖,需要注意的是这个方法必须是 public 类型。


当程序中有很多个地方需要用到依赖注入时,我们就需要一个类来专门负责管理创建所需的类,并创建它所有可能用到的依赖,这个类就是依赖注入容器。我们可以把依赖注入容器看作一个创建对象的工厂,负责向外提供被请求要创建的对象,同时提供对象生命周期的管理。


目录
相关文章
|
11月前
|
存储 Java 数据库
几分钟带你快速了解Spring框架理论知识!
几分钟带你快速了解Spring框架理论知识!
|
2月前
|
Java 程序员 容器
十分钟搞懂依赖注入
依赖注入(DI)是软件开发中的关键技术,它将类的依赖关系转移至外部管理,提升了代码的模块化和可测试性。如同炒菜时调料不由厨师直接添加,而是由调料师准备并递送,程序员只需声明所需依赖,外部机制如DI容器会负责实例化并注入这些依赖。这样,类变得更灵活且易于测试,同时也促进了代码的模块化。例如,在Java中,可以通过构造函数注入Logger接口的不同实现(如ConsoleLogger和FileLogger),使Application类与其具体实现解耦。
|
4月前
|
设计模式 黑灰产治理
三分钟带您搞懂代理模式
三分钟带您搞懂代理模式
|
5月前
|
XML Java 数据格式
🚀今天,我们来详细的聊一聊SpringBoot自动配置原理,学了这么久,你学废了吗?
🚀今天,我们来详细的聊一聊SpringBoot自动配置原理,学了这么久,你学废了吗?
109 0
|
监控 NoSQL 安全
Spring Boot 怎么做监控?这篇总算整明白了。。。
Spring Boot 怎么做监控?这篇总算整明白了。。。
2103 8
Spring Boot 怎么做监控?这篇总算整明白了。。。
|
消息中间件 存储 缓存
国庆假期,整整七天,我用76张图把Spring AOP给画明白了!
国庆假期,整整七天,我用76张图把Spring AOP给画明白了!
|
JSON Prometheus 监控
Spring Boot 怎么做监控?这篇总算整明白了。。。(2)
Spring Boot 怎么做监控?这篇总算整明白了。。。(2)
210 0
Spring Boot 怎么做监控?这篇总算整明白了。。。(2)
|
Java Spring
一图搞懂Spring Bean载入ioc过程以及生命周期 ✨ 每日积累
一图搞懂Spring Bean载入ioc过程以及生命周期 ✨ 每日积累
一图搞懂Spring Bean载入ioc过程以及生命周期 ✨ 每日积累
|
Java 数据库连接 数据库
信不信十分钟让你彻底搞懂java反射
概念:反射是Java的一种机制,让我们可以在运行时获取类的信息 作用:通过反射,我们可以在程序运行时动态创建对象,还能获取到类的所有信息,比如它的属性、构造器、方法、注解等;
18059 2
信不信十分钟让你彻底搞懂java反射
|
Java 测试技术 Maven
花了2个钟才搞懂这AOP为啥没生效,水友却睡着了……
Springboot中AOP失效的原因 今天 4ye 来和小伙伴们分享一个小实战啦 ,冲冲冲~ (。・∀・)ノ 实战回顾 (我居然拖到现在才写了这文章…… 😵) 主要是在一个周日(2020.6.6)在技术群里看到一个老哥在问 “怎么用切面来捕获自定义异常?” ( ̄▽ ̄)" 我当时想的是,捕获异常不是很常见的吗,平时经常用到这个全局异常捕获 ,于是就把自己 GitHub 上的小例子发给他(主要是这个 ControllerAdvice 注解),如图 👇 结果老哥过了一段时候就加了我,还问我有没有空帮忙看下,还
274 0