8 ioc 一 初体验。 (上手笔记)

133 阅读1分钟

一 what is ioc

ioc Inversion of Control 获得依赖对象的过程由自身管理变为了由IOC容器主动注入。

二 基础体验

2.1 how 写法。

//传统写法。
IService s1 = new MyService1();
s1.show();

//ioc 写法。
ServiceCollection serviceDescriptors = new ServiceCollection();
serviceDescriptors.AddTransient<IService, MyService1>();
ServiceProvider sProvider =  serviceDescriptors.BuildServiceProvider();
IService s2 = sProvider.GetService<IService>();
s2.show();

2.2 写法差异,适用场景

1 传统的 new ,是写散到各地的。 通过ioc ,可以全局跟一个ioc 容器,配置抽象和具体普通。 [方便维护]
2 创建A 时,可能需要B.B 可能需要C. 传统写法很蛋疼。 [ioc 则写得很轻松]

三 三种生命周期 。

3.1 瞬时生命周期 。

ServiceCollection serviceDescriptors = new ServiceCollection();
serviceDescriptors.AddTransient<IService, MyService1>();
ServiceProvider sProvider =  serviceDescriptors.BuildServiceProvider();
IService s1 = sProvider.GetService<IService>();
IService s2 = sProvider.GetService<IService>();
IService s3 = sProvider.GetService<IService>();

Console.WriteLine($"s1 hashCode {s1.GetHashCode()}");
Console.WriteLine($"s2 hashCode {s2.GetHashCode()}");
Console.WriteLine($"s3 hashCode {s3.GetHashCode()}");

image.png

3.2 作用域生命周期

ServiceCollection serviceDescriptors = new ServiceCollection();
serviceDescriptors.AddScoped<IService, MyService1>();
ServiceProvider sProvider =  serviceDescriptors.BuildServiceProvider();
IService s1 = sProvider.GetService<IService>();
IService s2 = sProvider.GetService<IService>();


ServiceProvider sProvider2 = serviceDescriptors.BuildServiceProvider();
IService s3 = sProvider2.GetService<IService>();
IService s4 = sProvider2.GetService<IService>();

Console.WriteLine($"s1 hashCode {s1.GetHashCode()}");
Console.WriteLine($"s2 hashCode {s2.GetHashCode()}");
Console.WriteLine($"s3 hashCode {s3.GetHashCode()}");
Console.WriteLine($"s4 hashCode {s4.GetHashCode()}");

同一provider 注册的相同。
image.png

四 一些花里胡哨的写法。

serviceDescriptors.AddScoped(typeof(IService), typeof(MyService1));

serviceDescriptors.AddScoped(typeof(IService), provider=> {
    //可自行决定一些创建对象的细节。
    return new MyService1();
});

//直接具体点。
serviceDescriptors.AddTransient<MyService1>();
//or 这样写。
serviceDescriptors.AddTransient(typeof(MyService1));

ServiceProvider sProvider =  serviceDescriptors.BuildServiceProvider();
IService s1 = sProvider.GetService<MyService1>(); //用的时候也具体。
s1.show();

五 在.net 6 中的使用。

#region 注入
builder.Services.AddTransient<IMyService, MyService1>();
#endregion

//控制器使用。
        private readonly IMyService _myService;
        public WeatherForecastController(ILogger<WeatherForecastController> logger, IMyService  s1)
        {
            _logger = logger;
            _myService = s1;
            s1.show();
        }