ASP.NET Core 6.0 ServiceCollection 实现依赖注入

ASP.NET Core6 lOC容器

控制反转(Inversion of Control, IoC)是一种软件设计模式,其目的是降低代码之间的耦合度。在C#中,可以使用依赖注入(Dependency Injection, DI)来实现控制反转。

一般系统分为 UI 层、BLL 层、DAL 层、IBLL 层 和 IDAL 层,IOC 实质是通过抽象 IBLL(接口、抽象类、普通父类)获取BLL层的实例,如果使用依赖注入,那么各层的关系如下:

内置容器 ServiceCollection 的应用

新建 Learn.NET6.Business.Interfaces 类库,新建 IMicrophone接口:

    public interface IMicrophone
    {

    }

在 Learn.NET6.ExceptionService 层添加 Microphone 类:

    public class Microphone : IMicrophone
    {
        public Microphone()
        {
            Console.WriteLine($"{this.GetType().Name}被构造。。");
        }
    }

新建 Learn.NET6.DemoTest 控制台应用程序,在 Program 类中:

需要注意的是 ServiceCollection 只支持构造函数注入。

{
    //传统做法,创建一个实例
    Microphone microphone = new Microphone();
    IMicrophone microphone1 = new Microphone();

}

//内置容器:
{
    //1.创建一个容器
    //nuget 引入 Microsoft.Extensions.DependencyInjection
    ServiceCollection serviceDescriptors = new ServiceCollection();
    //2.注册抽象和具体普通类之间的关系
    serviceDescriptors.AddTransient<IMicrophone, Microphone>();
    //3. serviteDescriptors.builder
    ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();

    IMicrophone microphone = serviceProvider.GetService<IMicrophone>();
}

IOC容器-DI依赖注入

依赖注入

在创建对象的实例时,如果对象A,依赖于对象B,对象B依赖于对象C,那么在创建对象A的时候,

自动的把对象C创建出来交给对象B,再把对象B创建出来交给对象A,从而创建出对象A。

可以在全局跟一个ioc容器,配置抽象和具体普通之间的关系的时候,可以修改,这里修改了,获取实例就获取新的实例。

在 Learn.NET6.ExceptionService. 新建 AndroidPhone、ApplePhone、Headphone、Microphone、MicrophoneNew 和 Power 类,多个类且类之间互相引用:

public class AndroidPhone : IPhone
{
    public IMicrophone Microphone { get; set; }
    public IHeadphone Headphone { get; set; }
    public IPower Power { get; set; }

    public AndroidPhone()
    {
        Console.WriteLine("{0}构造函数", this.GetType().Name);
    }

    public void Call()
    {
        Console.WriteLine("{0}打电话", this.GetType().Name); ;
    }

    public void Init123456678890(IPower iPower)
    {
        Power = iPower;
    }

    public void Text()
    {
        Console.WriteLine("{0}发信息", this.GetType().Name); ;
    }

    public object QueryUser(object opara)
    {
        throw new NotImplementedException();
    }
}
public class ApplePhone : IPhone
{
    public IMicrophone Microphone { get; set; }
    public IHeadphone Headphone { get; set; }
    public IPower Power { get; set; }

    public ApplePhone(IHeadphone iHeadphone)
    {
        this.Headphone = iHeadphone;
        Console.WriteLine("{0}带参数构造函数", this.GetType().Name);
    }

    public virtual void Call()
    {
        Console.WriteLine("{0}打电话", this.GetType().Name); ;
    }

    public void Text()
    {
        Console.WriteLine("{0}发信息", this.GetType().Name); ;
    }


    public object QueryUser(object opara)
    {
        return new
        {
            Id = 123,
            Name = "Richard",
            DateTiem = DateTime.Now.ToString()
        };
    }


    public void Init123456678890(IPower iPower)
    {
        this.Power = iPower;
    }
}
    public class Headphone : IHeadphone
    {

        public Headphone(IPower power)
        {
            Console.WriteLine($"{this.GetType().Name}被构造。。");
        }

    }
    public class Microphone : IMicrophone
    {
        public Microphone()
        {
            Console.WriteLine($"{this.GetType().Name}被构造。。");
        }
    }
    public class MicrophoneNew : IMicrophone
    {
        public MicrophoneNew()
        {
            Console.WriteLine($"{this.GetType().Name}被构造。。");
        }
    }
    public class Power : IPower
    {
        private IMicrophone Microphone;
        private IMicrophone Microphone2;

        public Power(IMicrophone microphone)
        {
            Console.WriteLine($"{this.GetType().Name}被构造。。");
            this.Microphone = microphone;
        }

        public Power(int microphone)
        {
            Console.WriteLine($"{this.GetType().Name}被构造。。");
        }

        public Power(IMicrophone microphone, IMicrophone microphone2)
        {
            Console.WriteLine($"{this.GetType().Name}被构造。。");
            this.Microphone = microphone;
            this.Microphone2 = microphone2;
        }
    }

 在 Learn.NET6.Business.Interfaces 新建 IHeadphone、IMicrophone、IPhone 和 IPower:

    public interface IHeadphone
    {

    }
    public interface IMicrophone
    {

    }
    public interface IPhone
    {
        void Call();

        void Text();

        void Init123456678890(IPower iPower);

        IMicrophone Microphone { get; set; }
        IHeadphone Headphone { get; set; }
        IPower Power { get; set; }
        object QueryUser(object opara);
    }
    public interface IPower
    {

    }

传统做法创建对象

{
    // 传统做法创建对象
    IMicrophone microphone = new Microphone();
    IPower power = new Power(microphone);
    IHeadphone headphone = new Headphone(power);
}

 IOC容器支持依赖注入

{
    //IOC容器支持依赖注入
    ServiceCollection serviceDescriptors = new ServiceCollection();
    serviceDescriptors.AddTransient<IMicrophone, Microphone>();
    serviceDescriptors.AddTransient<IPower, Power>();
    serviceDescriptors.AddTransient<IHeadphone, Headphone>();
    ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();

    IHeadphone headphone = serviceProvider.GetService<IHeadphone>();
}

ServiceCollection 支持的生命周期

ServiceCollection--IOC容器本质就是来创建对象的;

那么在对象创建的时候,有些特殊的场景,需要创建出来的对象有的支持单例,有的在一些范围内支持单例,面对于这些诉求,ServiceCollection支持了三种生命周期来解决这个问题。

瞬时生命周期--Transient

//一、AddTransient:瞬时生命周期,每一次创建都是一个全新的实例
{
    ServiceCollection serviceDescriptors = new ServiceCollection();
    serviceDescriptors.AddTransient<IMicrophone, Microphone>();
    ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();
    IMicrophone microphone1 = serviceProvider.GetService<IMicrophone>();
    IMicrophone microphone2 = serviceProvider.GetService<IMicrophone>();
    IMicrophone microphone3 = serviceProvider.GetService<IMicrophone>();
    IMicrophone microphone4 = serviceProvider.GetService<IMicrophone>();
    // 比较内存的引用地址,如果相同就表示同一个对象,结果是不相同
    Console.WriteLine($"microphone1 比较 microphone2:{object.ReferenceEquals(microphone1, microphone2)}");
    Console.WriteLine($"microphone1 比较 microphone3:{object.ReferenceEquals(microphone1, microphone3)}");
    Console.WriteLine($"microphone2 比较 microphone4:{object.ReferenceEquals(microphone2, microphone4)}");

}

单例生命周期--Singleton

//一、AddSingleton:单例生命周期,每一次创建都是同一个实例
{
    ServiceCollection serviceDescriptors = new ServiceCollection();
    serviceDescriptors.AddSingleton<IMicrophone, Microphone>();
    ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();
    IMicrophone microphone1 = serviceProvider.GetService<IMicrophone>();
    IMicrophone microphone2 = serviceProvider.GetService<IMicrophone>();
    IMicrophone microphone3 = serviceProvider.GetService<IMicrophone>();
    IMicrophone microphone4 = serviceProvider.GetService<IMicrophone>();
    // 比较内存的引用地址,如果相同就表示同一个对象,结果是相同
    Console.WriteLine($"microphone1 比较 microphone2:{object.ReferenceEquals(microphone1, microphone2)}");
    Console.WriteLine($"microphone1 比较 microphone3:{object.ReferenceEquals(microphone1, microphone3)}");
    Console.WriteLine($"microphone2 比较 microphone4:{object.ReferenceEquals(microphone2, microphone4)}");
}

作用域生命周期--Scoped

//一、AddScoped:作用域生命周期,同一个serviceProvider获取到的是同一个实例
{
    ServiceCollection serviceDescriptors = new ServiceCollection();
    serviceDescriptors.AddScoped<IMicrophone, Microphone>();
    ServiceProvider serviceProvider1 = serviceDescriptors.BuildServiceProvider();
    IMicrophone microphone1 = serviceProvider1.GetService<IMicrophone>();
    IMicrophone microphone2 = serviceProvider1.GetService<IMicrophone>();

    ServiceProvider serviceProvider2 = serviceDescriptors.BuildServiceProvider();
    IMicrophone microphone3 = serviceProvider2.GetService<IMicrophone>();
    IMicrophone microphone4 = serviceProvider2.GetService<IMicrophone>();

    // 比较内存的引用地址
    Console.WriteLine($"microphone1 比较 microphone2:{object.ReferenceEquals(microphone1, microphone2)}"); //True
    Console.WriteLine($"microphone3 比较 microphone4:{object.ReferenceEquals(microphone3, microphone4)}"); //True
    Console.WriteLine($"microphone1 比较 microphone3:{object.ReferenceEquals(microphone1, microphone3)}"); //False
    Console.WriteLine($"microphone1 比较 microphone1:{object.ReferenceEquals(microphone1, microphone4)}"); //False
}

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜飞鼠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值