03_03_依赖注入多种方式
注入方式
但凡是能往你这个类里面传东西的
属性注入、
方法注入、
特性注入(无法单独存在,只是对前两种属性或方法的修饰补充,区分哪些注入),都可以注入
asp.netcore原生只支持构造函数注入
在某些场景下才支持(没办法)
Blazor ==》支持特性、属性,没有构造函数,只能用其它代替
WebAPI==》控制器(Action支持方法注入),MiniAPI没有控制器的API,也是Action方法,只是方法没有类型,所以必须要支持方法注入,[FormServices]
二、依赖注入和服务定位
1、谁再用
依赖注入:不体现服务容器,只是自己需要的类型参数,注入是无感的,是框架第三方自己注入进来的,
服务容器的使用者是框架,不是业务代码,只是在注册的时候注册了
服务定位:可以看到服务容器的依赖,代码在用,不叫控制反转了
我们自己去冰箱拿东西了,没有控制反转,就不叫依赖注入了,和自己new没区别
我们明确定义了容器的存在,并且自己从容器里面拿,
2、推拉差异
依赖注入模式,实例是被推进来的
服务定位,是拉取所需要的实例
一个无感,一个自己去拿
服务定位器不被选择的原因?
违背了高内聚低耦合的原则
服务之间的依赖关系应该是明确的,而不应该是模糊的,依赖不明确,都拿过来了,
属性注入、方法注入同理,也是依赖不明确
一个服务依赖另一个服务==》基于类型的依赖,无论是基于服务的接口还是实现类,都是基于契约的一种依赖,这种依赖是明确的
服务定位器是一种黑盒子,能提供所需的所有东西,前提是所需要的注册都添加到容器里,依赖是模糊的,怎么知道有没有被注册?
写这个类
ServiceProvider.GetRequiredService<IAccount>()
的时候不知道,就是一种不安全感
而构造函数注入,一定会知道会被注入进来,明确的,如果不能注入,实例就无法创建,代码运行不了
如果类型的构造函数无法满足,类型就无法被构建,这就是明确的依赖
public static class Sample03 { public interface IMessageService { } public class EmailMessageService(IAccount account, ITool tool) : IMessageService { public IAccount Account { get; set; } = account; public ITool Tool { get; set; } = tool; public void Test() { Console.WriteLine(Account.GetHashCode()); Console.WriteLine(Tool.GetHashCode()); } } public class SmsMessageService(IServiceProvider serviceProvider) : IMessageService { public IServiceProvider ServiceProvider { get; set; } = serviceProvider; public void Test() { Console.WriteLine(ServiceProvider.GetRequiredService<IAccount>().GetHashCode()); Console.WriteLine(ServiceProvider.GetRequiredService<ITool>().GetHashCode()); } } }
属性注入、方法注入只有在类型被构建完成以后才能使用
构建完成之后,你才能知道你的依赖是否被注入了,依赖注入被推迟了,这就会绕过构造函数的限制
不应该当成我们常规的开发方式
浙公网安备 33010602011771号