.net core中的依赖注入是什么样的?
前言:
想必大家学习.net core的过程中,总会听到很多名词,比如:依赖注入,控制反转,切面编程,DDD领域驱动设计,仓储等等。今天也是记录一下,自己学习过程中对依赖注入和控制反转的理解吧!
1.什么是依赖注入?
提到依赖注入,大家一定会想到控制反转,怎么了解,控制反转是一种设计原则(Inversion of Control,缩写为IoC),而依赖注入((Dependency Injection,简称DI))是它的一种实现方式。
2.依赖注入的目的是为了什么?
控制反转用于解耦,将接口和实现的耦合降低,有一个好处就是,一个接口,可以进行不同的实现,这样提高扩展性,确保代码的可维护性和扩展性。通俗的讲,就是对象在被使用前,我们需要New一下对象,创建一个实例对象,然后在进行其他操作,依赖注入是针对接口API的。
3.怎么使用?
.net core 自带了依赖注入的框架,也可以使用第三方DI框架,比如
- Autofac
- DryIoc
- Grace
- LightInject
- Lamar
- Stashbox
- Unity)
本文讲讲内置DI,使用到的组件包
Microsoft.Extensions.Dependencylnjection.Abstractions
Microsoft.Extensions.Dependency
3.1将接口和实现类使用依赖注入方式添加到容器中
services.AddSingleton<接口,实现类>();【单例】
3.2在构造函数中获取注入的服务:
这种方式获取的注入的服务,在整个Controller都可以使用
3.3在视图中获取注入的配置服务:
3.4在视图中获取注入的服务:
3.5在方法中获取注入的服务:
Mehtod([FromServices] ITest test)
这种方式获取的服务是局部变量,使用特别的API调用的服务。
4.核心类型
- IServiceCollection:服务的注册
- ServiceDescriptor: 注册服务的信息
- IServiceProvider:容器
- IServiceScope:子容器的生命周期
ServiceLifetime(生命周期):
- Singleton(单例):每次请求的对象都是同一个实例【使用范围:我们编写的接口和实现类,一般使用单例模式】
- Scoped(作用域):在一次请求内(作用域内)的对象是一样的【适用范围:数据库的上下文】
- Transient(瞬时【短暂】):每次请求都是一个新对象,比如一个接口,很3个不同实现,每次请求都是三个不同的对象【还没用到过,用到来补充】
5.注入方式
依赖注入的方式还是有很多,比如常规,泛型,工厂等等。
5.1 常规的注入方式:
services.AddSingleton<接口, 实现类>()
这种方式比较简单,这里是拿单例模式举例子,其他模式也是一样的格式,一个接口可以对应一个实现类,如果你注入2个单例,都是针对一个接口,当你获取服务的时候,你只会得到一个服务实例,那就是最后注入的那个服务。
5.2 泛型的注入方式:
services.AddSingleton(typeof(泛型接口<>),typeof(泛型实现类<>))
这种方式,说实话我也是第一次使用,有好处,我们不需要指明确定的接口和实现类,而是你看你怎么用,还是贴代码,请看如下代码:
services.AddSingleton(typeof(IGroup<>),typeof(Group<>));
一开始还不理解,为什么要使用泛型注入,脑壳开窍了!其实这个泛型注入,是在你注入其他一些接口和现实类之后,想对已经注入一些接口,编写共同的一个方法,然后调用,这样可以提高代码的使用率,还是画图吧!
使用泛型注入的好处,大家也可以显而易见,通过泛型,我们可以在泛型类中定义公共方法,提高代码的复用!
将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型
5.3 工厂的注入方式:
services.AddSingleton<ITest>(serviceProvider=>
{
return new Test001();
});
使用工厂模式,它必须返回的是一个实例对象,serviceProvider【The factory that creates the service】】有GetService(),GetRequiredService,GetServices()方法,可以做一些复杂的组装(这个还不理解,没用过,慢慢学习,用到了过来补充)。
总结
通过以上学习,并了解了.net core种使用依赖注入的方式,可以将我们的接口和实现类注入到容器中,后期想要获取服务,我们可以通过构造控制器的构造函数获取或直接通过[FromService 接口]获取服务,依赖注入的方式帮我们解决了调用一个对象,使用new的方式去构建,依赖注入还有3个生命周期进行注入:AddSingleton(单例)、AddScoped(范围)、AddTransient(瞬时),注入服务可以使用泛型,工厂的方式注册。