内置IOC容器ServiceCollection

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内置IOC容器ServiceCollection相关的知识,希望对你有一定的参考价值。

.NetCore内置IOC容器ServiceCollection

一、IOC介绍

IOC:全名(Inversion of Control)-控制反转

IOC意味着我们将对象的创建控制权交给了外部容器,我们不管它是如何创建的,我们只需要知道,当我们想要某个实例时,我们可以直接从这个外部容器中去拿,而再也不需要我们去new了,充分体现了DIP(依赖倒置原则),也体现了我们经常挂在嘴边的面向接口编程。

DI:全名(Dependency Injection)-依赖注入

DI意味着将类型之间的依赖关系注入到DI容器中

在之前的.Net Framework中并没有集成IOC,虽然Microsoft自己有一套"Unity",想要使用IOC+DI时,还需要我们自己去安装包,进行三部曲等等各种操作

比较流行的IOC容器技术:Autofac、Unity、NInject。。。

二、.NetCore内置IOC容器ServiceCollection

1、打开NuGet包管理器,安装 Microsoft.Extensions.DependencyInjection 包

2、实现代码如下:

public interface ISqlHelper

    void GetAll();

public class SqlServerHelper : ISqlHelper

    public void GetAll()
    
        Console.WriteLine("this is "+typeof(SqlServerHelper));
    

static void Main(string[] args)

    ServiceCollection services = new ServiceCollection();
    services.AddTransient<ISqlHelper, SqlServerHelper>();
    var provider=services.BuildServiceProvider();
    var sqlHelper=provider.GetService<ISqlHelper>();
    sqlHelper.GetAll();
    Console.ReadKey();

运行结果输出:this is SqlServerHelper

当我们在执行业务逻辑时想要写入一些日志(Log),必然会当然依赖这个类,那么会形成了SqlHelper类与Log类之前的依赖关系,我们可以将之前的依赖关系转移到DI容器中,也就是依赖注入(DI),然后在DI容器获取服务(对象)

示例代码如下:

public interface ISqlHelper 

    void GetAll();

public class SqlServerHelper : ISqlHelper 

    private readonly ILog _ilog;

    public SqlServerHelper(ILog ilog) 
    
        _ilog = ilog;
    
    public void GetAll() 
    
        _ilog.LogInfo($"我在typeof(SqlServerHelper).Name中,我是ilog");
        Console.WriteLine("this is " + typeof(SqlServerHelper).Name);
    

public interface ILog 

    void LogInfo(string msg);

public class Log : ILog 

    public void LogInfo(string msg) 
    
        Console.WriteLine(msg);
    

private static void Main(string[] args) 

    services.AddTransient<ILog, Log>();//瞬时注入
    services.AddTransient<ISqlHelper, SqlServerHelper>();//瞬时,每次的实例都是一个新的对象
    var provider = services.BuildServiceProvider();//构建服务提供商
    var sqlHelper = provider.GetService<ISqlHelper>();//获取我们需要的服务实例
    sqlHelper.GetAll();
    Console.ReadKey();

如果如下:

我在SqlServerHelper中,我是ilog
this is SqlServerHelper

三、组件的生命周期

1、Transient:瞬时,每次的实例都是一个新的对象

2、Singleton:单例,全局唯一实例

3、Scoped:作用域,在一个作用域中唯一实例,比如在Asp.Net Core应用程序中一次请求相当于一个Scoped

Transient:瞬时,每次的实例都是一个新的对象

ServiceCollection services = new ServiceCollection();
services.AddTransient<ILog, Log>();
services.AddTransient<ISqlHelper, SqlServerHelper>();
var provider = services.BuildServiceProvider();
var sqlHelper = provider.GetService<ISqlHelper>();//首次获取要使用的服务
sqlHelper = provider.GetService<ISqlHelper>();//获取新的服务
sqlHelper.GetAll();
瞬时

结果如下:

瞬时结果

Singleton:单例,全局唯一实例

ServiceCollection services = new ServiceCollection();
services.AddSingleton<ILog, Log>();
services.AddSingleton<ISqlHelper, SqlServerHelper>();
var provider = services.BuildServiceProvider();
var sqlHelper = provider.GetService<ISqlHelper>();
sqlHelper = provider.GetService<ISqlHelper>();
sqlHelper.GetAll();
Console.ReadKey();
单例

Scoped:作用域,在一个作用域中唯一实例

一个作用域

ServiceCollection services = new ServiceCollection();
services.AddScoped<ILog, Log>();
services.AddScoped<ISqlHelper, SqlServerHelper>();
var provider = services.BuildServiceProvider();
var scope1 = provider.CreateScope();//在一个作用域下创建第一个子作用域       
var sqlHelper = scope1.ServiceProvider.GetService<ISqlHelper>();

新的作用域

ServiceCollection services = new ServiceCollection();
services.AddScoped<ILog, Log>();
services.AddScoped<ISqlHelper, SqlServerHelper>();
var provider = services.BuildServiceProvider();
var scope1 = provider.CreateScope();
//在一个作用域下创建第一个子作用域       
var sqlHelper = scope1.ServiceProvider.GetService<ISqlHelper>();
var scope2 = provider.CreateScope();
//在一个作用域下创建第二个子作用域
sqlHelper = scope2.ServiceProvider.GetService<ISqlHelper>();

注意:由于是控制台项目,只能用子作用域来体现作用域的特点,在web项目中,一次请求就相当于一个作用域

推荐阅读

资料参考

  • • ServiceCollection 类 (Microsoft.Extensions.DependencyInjection) | Microsoft Learn[1]

  • • ASP.NET Core 中的 ServiceProvider - hippieZhou - 博客园[2]

欢迎关注我的公众号“Net分享”,技术文章第一时间推送 , 分享一些你可能注意不到的细节。

 

引用链接

[1] ServiceCollection 类 (Microsoft.Extensions.DependencyInjection) | Microsoft Learn: https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.extensions.dependencyinjection.servicecollection?view=dotnet-plat-ext-6.0
[2]https://blog.csdn.net/m1m2m3mmm/article/details/123231352

以上是关于内置IOC容器ServiceCollection的主要内容,如果未能解决你的问题,请参考以下文章

.net core反射练习-简易版IOC容器实现

ASP.NET Core Web 应用程序系列- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)

ASP.NET Core Web 应用程序系列- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入

[IoC容器Unity]第二回:Lifetime Managers生命周期

用Autofac替换.net core 内置容器

Spring--2.Spring之IOC--IOC容器的22个实验