springboot抽象类可以依赖注入吗_.net core的依赖注入你了解吗

1.ServiceCollection(依赖注入的容器)

ServiceCollection:ICollection作为依赖注入的容器,它存在一个List用来存放所有的注入到容器中的类型

这里以注入单例模式执行过程为例为例:

16a6e66295c9b1a3915b879ec72aa5c2.png

注入流程

5859cb72e8b56d48dae513f0e64b1111.png

注入后的容器

2.ServiceDescriptor(注入服务描述器)

private ServiceDescriptor(Type serviceType, ServiceLifetime lifetime){            this.Lifetime = lifetime;            this.ServiceType = serviceType;}//标准的注入public ServiceDescriptor(Type serviceType, Type implementationType, ServiceLifetime lifetime) : this(serviceType, lifetime){            if (serviceType == null) {throw new ArgumentNullException("serviceType");}            if (implementationType == null) {throw new ArgumentNullException("implementationType"); }            this.ImplementationType = implementationType;}//Singleton模式public ServiceDescriptor(Type serviceType, object instance) : this(serviceType, ServiceLifetime.Singleton) {     //校验省略            this.ImplementationInstance = instance;}//工厂模式,通过ServiceProvider的Func注入public ServiceDescriptor(Type serviceType, Func factory, ServiceLifetime lifetime) : this(serviceType, lifetime) {//校验省略        this.ImplementationFactory = factory;}

3.ServiceProvider(实例化器)

 var provider = services.BuildServiceProvider();
7257fa6245b678deac2dfea4f1927546.png

以Transient实例化详细执行流程如下图:

var orderService = provider.GetService();
83dc3b9e54879b7e4aa4d521c5e86662.png

Singleton,Scope,Transient三种模式下的产生对象实例的流程如下:

49b500555d5865a99ffb78a145e819f6.png

4.IServiceScope

创建作用域,也就是创建子容器

单例模式是在Root容器下的,只能程序停止时释放,Transient模式,每次都会产生新的实例,所以两者应用不多。我们可以使用Scope的实例测试。

1.准备服务类 public interface IOrderService    {    }    public class DisposableOrderService : IOrderService, IDisposable    {        public void Dispose()        {            Console.WriteLine($"DisposableOrderService Disposed:{this.GetHashCode()}");        }    }2.注入为Scope    services.AddScoped();    3.1调用       [HttpGet]        public int Get(            [FromServices] IOrderService aaa,            [FromServices] IOrderService bbb,            [FromServices]IHostApplicationLifetime hostApplicationLifetime,             [FromQuery]bool stop = false)        {            return 1;        }                【结果,只会打印一次,被释放的信息,因为aaa,bbb是同一个实例】3.2 新建scope调用         [HttpGet]        public int Get(            [FromServices] IOrderService aaa,             [FromServices] IOrderService bb,            [FromServices]IHostApplicationLifetime hostApplicationLifetime,             [FromQuery]bool stop = false)        {            using (IServiceScope scope = HttpContext.RequestServices.CreateScope())            {                var service = scope.ServiceProvider.GetService();            }            return 1;        }                【结果,会打印两次,被释放的信息。因为在scope内,相当于创建了一个子容器,重新创建一个是实例】

5.容器使用注意事项

1.容器会管理释放自己创建的对象,所以我们不要手动创建对象,然后放入容器。如果实现了IDisable接口,容器会帮助我们管理生命周期,调用Dispose方法。

只有Singleton接口可以直接传入一个new 的对象,其他两个接口的工厂模式和类型注入的模式的效果时一样的1.创建的实例由容器控制释放service.AddSignleton();2.实例的生命周期不由容器控制释放service.AddSingleton(new OrderService()));

2.单例是注入到应用程序的根容器(Root)中,根容器是伴随整个应用程序存在的。如果使用根容器获取Transient对象,那么将会永远存在整个应用程序周期中,不会释放。所以不要在跟容器中获取Transient对象

//跟容器是存放单例模式的,如果通过根容器获取临时对象,临时对象是不会被释放的。ApplicationService就是根容器app.ApplicationService.GetService();

3.ServiceCollection支持一个接口多个实现同时注入。

4.如果是在整个类中使用的对象,可以使用构造函数注入,如果仅仅是某个方法使用,那么可以通过属性标签的方式注入[FromService]

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页