02_05_生命周期管理

一、服务的生命周期

代表一个服务实例的生命周期,也就是对象,类型是一致存在的

通过服务构建出来的对象的生命周期

 

为什么要有对象的生命周期呢?

因为一个应用的依赖注入系统,往往管理着整个应用的实例,有着不同的使用场景

1、瞬时(每次从依赖注入系统里面获取,都会创建一个全新的对象,不会保存)

在一个方法里new了某个类,可能只是在这个方法里面用,用完方法结束就没了,这就是没有生命期的,用完就抛弃了,就是瞬时,用的最多的,不会保存

2、单例(第一次从依赖注入系统获得,才会创建一个全新的对象,会保存,后面都是这一个对象,反复使用)

一个类型new出来之后,在整个应用里面一直存在的,而且只有一个,除非你重开,只在启动的时候被new一下

 

不管是高贵的单例对象,还是没有人权的普通的瞬时对象,都是依赖注入系统里面的一员

 3、作用域(看情况保存)

asp.net core里面,一个请求就是一个作用域,一个http请求,不同的请求就是不同的作用域

在同一个请求里面,获取作用域的实例,跟获取单例的实例看起来是一个样的

可以理解为也是一种单例,但是只是在一定范围内单例

不同作用域不会互相干涉

 

 

 

 

二、服务容器

根容器:初创只有一个

子容器:可以有很多个

 

根容器A,对于子容器bcd,都是可见的,但是子容器是互相不可见的

作用域就是子容器,相互不可见

瞬时对象是不会被保存在任何容器里,所以就是一次性的

 

通过根容器创建这个容器的子容器 var child1 = root.CreateScope().ServiceProvider;

public static class Sample03
{
    public class Base
    {
        protected Base()
        {
            Console.WriteLine($"Created:{GetType().Name}");
        }

    }

    public class Account: Base, IAccount{}
    public class Message:Base, IMessage{}
    public class Tool:Base, ITool{}

    public static void Run()
    {
        var root = new ServiceCollection()
            .AddTransient<IAccount, Account>()
            .AddScoped<IMessage, Message>()
            .AddSingleton<ITool, Tool>()
            .BuildServiceProvider();
        var child1 = root.CreateScope().ServiceProvider;
        var child2 = root.CreateScope().ServiceProvider;

        GetService<IAccount>(child1);
        GetService<IMessage>(child1);
        GetService<ITool>(child1);
        Console.WriteLine();
        GetService<IAccount>(child2);
        GetService<IMessage>(child2);
        GetService<ITool>(child2);
    }

    private static void GetService<T>(IServiceProvider provider)
    {
        provider.GetService<T>();
        provider.GetService<T>();
    }
}

Created:Account
Created:Account
Created:Message
Created:Tool

Created:Account
Created:Account
Created:Message

 

瞬时每次都会创建,共4次

作用域创建2次

单例只会第一次创建,根容器已经存在就直接拿了

 

 

 三、释放策略

同样根生命周期有关,如果采用了瞬时和作用域两种,并且实现了IDisposable接口,就会被当前子容器保存,子容器销毁的时候会被释放

单例对象保存在根容器,根容器销毁,才会释放

容器里面的实例什么时候被释放,是跟随容器的

 瞬时虽然不会保存,但是也不会被立马释放掉,也会随着子容器的销毁,才会被释放

public static class Sample04
{
    public class Base : IDisposable
    {
        protected Base()
        {
            Console.WriteLine($"Created:{GetType().Name}");
        }

        public void Dispose()
        {
            Console.WriteLine($"Disposed: {GetType().Name}");
        }
    }

    public class Account: Base, IAccount{}
    public class Message:Base, IMessage{}
    public class Tool:Base, ITool{}

    public static void Run()
    {
        using var root = new ServiceCollection()
            .AddTransient<IAccount, Account>()
            .AddScoped<IMessage, Message>()
            .AddSingleton<ITool, Tool>()
            .BuildServiceProvider();

        using (var scope = root.CreateScope())
        {
            var child = scope.ServiceProvider;
            child.GetService<IAccount>();
            child.GetService<IMessage>();
            child.GetService<ITool>();
            Console.WriteLine("释放子容器");
        }
        Console.WriteLine("释放根容器");
    }
}

Created:Account
Created:Message
Created:Tool
释放子容器
Disposed: Message
Disposed: Account
释放根容器
Disposed: Tool

 

 

 

posted on 2026-01-26 14:36  张彦山  阅读(2)  评论(0)    收藏  举报