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());
        }
    }

}

 

属性注入、方法注入只有在类型被构建完成以后才能使用

构建完成之后,你才能知道你的依赖是否被注入了,依赖注入被推迟了,这就会绕过构造函数的限制

不应该当成我们常规的开发方式

 

posted on 2026-01-26 18:26  张彦山  阅读(5)  评论(0)    收藏  举报