作用域主要由 IServiceScope 这个接口来承载
对于实现 IDisposable 类的实例的对象,容器会负责对其生命周期进行管理,使用完毕之后,他会释放这些对象
实现 IDisposable 接口类型的释放:
两点建议:
演示代码: https://github.com/witskeeper/geektime/tree/master/samples/DependencyInjectionScopeAndDisposableDemo
先看一下服务
namespace DependencyInjectionScopeAndDisposableDemo.Services
{
public interface IOrderService
{
}
public class DisposableOrderService : IOrderService, IDisposable
{
public void Dispose()
{
Console.WriteLine($"DisposableOrderService Disposed:{this.GetHashCode()}");
}
}
}
首先定义 IOrderService
接着定义 IOrderService 的实现 DisposableOrderService,并实现了 IDisposable 这个接口
在释放的时候打印释放信息,并输出对象的 HashCode
接着是服务注册(Startup)
services.AddTransient<IOrderService,DisposableOrderService>();
这里先注册一个瞬时服务,将 IOrderService 注册进去
然后看一下控制器(WeatherForecastController)
[HttpGet]
public int Get([FromServices] IOrderService orderService,
[FromServices] IOrderService orderService2)
{
return 1;
}
这里 FromServices 获取了两次 IOrderService
这里不需要写任何代码对它进行操作,因为整个生命周期是由容器去管理的
启动程序,输出如下:
DisposableOrderService Disposed:10579059
DisposableOrderService Disposed:47945396
可以看出,执行完毕之后,DisposableOrderService 会被释放掉,并且两个对象都会被释放掉
两个对象的 HashCode 不同
瞬时服务在每一次获取的时候都会获得一个新的对象
接着,添加一行代码表示服务
[HttpGet]
public int Get([FromServices] IOrderService orderService,
[FromServices] IOrderService orderService2)
{
Console.WriteLine("接口请求处理结束");
return 1;
}
输出一下,表示我们的接口已经访问完毕,看一下释放时机在哪里
启动程序,输出如下:
接口请求处理结束
DisposableOrderService Disposed:35023218
DisposableOrderService Disposed:13943705
由此看出,接口请求处理结束后,才释放对象
接下来看一下 Scoped 模式
服务注册
services.AddScoped<IOrderService>(p => new DisposableOrderService());
控制器
[HttpGet]
public int Get([FromServices] IOrderService orderService,
[FromServices] IOrderService orderService2)
{
Console.WriteLine("=======1==========");
// HttpContext.RequestServices
// 是当前请求的一个根容器
// 应用程序根容器的一个子容器
// 每个请求会创建一个容器
using (IServiceScope scope = HttpContext.RequestServices.CreateScope())
{
// 在这个子容器下面再创建一个子容器来获取服务
var service = scope.ServiceProvider.GetService<IOrderService>();
}
Console.WriteLine("=======2==========");
Console.WriteLine("接口请求处理结束");
return 1;
}
启动程序,输出如下:
=======1==========
DisposableOrderService Disposed:31307802
=======2==========
接口请求处理结束
DisposableOrderService Disposed:31614998
每次请求会获得两个释放,意味着每创建一个 Scoped 的作用域,每个作用域内可以是单例的