ServiceCollection IOC容器 服务的生命周期

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
 
 
namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            //services.AddTransient<IFly, Pig>();
            //services.AddSingleton<IFly, Pig>();
            services.AddScoped<IFly, Pig>();
            
            services.AddLogging(options =>
            {
                options.AddConsole().SetMinimumLevel(LogLevel.Debug);
            });
 
            var provider = services.BuildServiceProvider();
            //验证scope生命周期
            var scope1 = provider.CreateScope();
            var service = scope1.ServiceProvider.GetService<IFly>();
 
            //var service = provider.GetService<IFly>();
 
            var scope2 = provider.CreateScope();
            var service2 = scope2.ServiceProvider.GetServices<IFly>();
 
            //var service2 = provider.GetService<IFly>();
            var logService = provider.GetService<ILoggerFactory>();
            service.Fly();
            
 
            Console.Read();
 
        }
    }
 
    public interface IFly
    {
        void Fly();
    }
 
    public class Pig : IFly
    {
        ILogger<Pig> logger = null;
        public Pig(ILoggerFactory loggerFactory)
        {
            Console.WriteLine("构造函数被调用");
 
           logger= loggerFactory.CreateLogger<Pig>();
        }
        public void Fly()
        {
            logger.LogDebug("这是Console的日志");
            Console.WriteLine("风口来了,猪都可以飞起来");
        }
    }
}


.net core系列之《.net core内置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。。。

二、.net core内置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();
}

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

示例代码如下:

public interface ILog
{
    void LogInfo(string msg);
}
public class Log : ILog
{
    public void LogInfo(string msg)
    {
        Console.WriteLine(msg);
    }
}
static void Main(string[] args)
{
    ServiceCollection services = new ServiceCollection();
    services.AddTransient<ILog, Log>();
    services.AddTransient<ISqlHelper, SqlServerHelper>();

    var provider=services.BuildServiceProvider();
    var sqlHelper= provider.GetService<ISqlHelper>();
    sqlHelper.GetAll();
    Console.ReadKey();
}

如果如下:
在这里插入图片描述

三、组件的生命周期

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

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

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

Transient

        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddTransient<ISqlHelper, SqlServerHelper>();
var provider=services.BuildServiceProvider();
            var sqlHelper=provider.GetService<ISqlHelper>();
            sqlHelper= provider.GetService<ISqlHelper>();

            Console.ReadKey();
        }

结果如下:
在这里插入图片描述
Singleton

        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddSingleton<ISqlHelper, SqlServerHelper>();
var provider=services.BuildServiceProvider();
            var sqlHelper=provider.GetService<ISqlHelper>();
            sqlHelper= provider.GetService<ISqlHelper>();

            Console.ReadKey();
        }

结果如下:
在这里插入图片描述
Scoped

1、一个作用域下:

        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddScoped<ISqlHelper, SqlServerHelper>();
var provider=services.BuildServiceProvider();
            var sqlHelper=provider.GetService<ISqlHelper>();
            sqlHelper= provider.GetService<ISqlHelper>();

            Console.ReadKey();
        }

结果如下:
在这里插入图片描述
2、二个作用域下:

static void Main(string[] args)
{
    ServiceCollection services = new ServiceCollection();
    services.AddScoped<ISqlHelper, SqlServerHelper>();
    var provider=services.BuildServiceProvider();
    var scope1=provider.CreateScope();//在一个作用域下创建第一个子作用域
    var scope2= provider.CreateScope();//在一个作用域下创建第二个子作用域
    var sqlHelper= scope1.ServiceProvider.GetService<ISqlHelper>();
    sqlHelper= scope2.ServiceProvider.GetService<ISqlHelper>();

    Console.ReadKey();
}

如果如下:
在这里插入图片描述
注意:由于是控制台项目,只能用子作用域来体现作用域的特点,在web项目中,一次请求就相当于一个作用域

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值