在 C# 中,依赖注入服务的生命周期指的是在应用程序中管理和控制依赖项注入服务对象的生命周期的方式。常见的生命周期包括瞬态(transient)、作用域(scoped)和单例(singleton)三种。
- 瞬态(Transient)生命周期:
瞬态生命周期是指每次从容器中请求服务时,都会创建一个新的实例。这意味着每次注入服务时都会得到一个新的对象,对象的生命周期仅在请求期间。适用于每次都需要新实例的场景。
- 应用场景:适用于需要频繁创建新实例的服务。每次请求时都会创建一个新的-对象,对象的生命周期仅限于当前请求或方法调用。
- 示例:适合轻量级临时对象或者对象内部状态随请求变化的情况。例如,一些计算服务或者临时数据处理服务。
services.AddTransient<IService, Service>();
- 作用域(Scoped)生命周期:
作用域生命周期是指在同一个作用域中,每次请求服务都会得到相同的实例,而不同作用域之间会有不同的实例。通常在每个 HTTP 请求或每个线程上下文中会创建一个新的作用域,服务的生命周期为整个作用域。适用于需要在同一个作用域内共享服务实例的场景。
- 应用场景:适用于需要在同一个作用域内共享实例的服务。通常在 Web 应用中,每个 HTTP 请求会创建一个作用域,该作用域内的服务实例在整个请求过程中都是同一个。
- 示例:在处理每个 HTTP 请求时,例如数据库上下文或者用户身份验证服务,保证在同一请求中使用相同的实例以确保数据一致性和请求隔离。
services.AddScoped<IService, Service>();
- 单例(Singleton)生命周期:
单例生命周期是指在整个应用程序生命周期中只会创建一个实例,所有请求都会共享同一个实例。适用于整个应用程序生命周期内只需要一个实例的场景。
- 应用场景:适用于整个应用程序生命周期内只需要一个实例的服务。这样可以确保所有请求共享同一个实例,节省资源并确保全局状态一致性。
- 示例:例如配置管理服务、日志服务或者缓存服务,这些服务在应用程序运行期间始终保持不变,并且需要在应用程序的各个部分共享相同的实例。
services.AddSingleton<IService, Service>();
使用示例
using Microsoft.Extensions.DependencyInjection;
using System;
namespace IOCTest
{
internal class Program
{
static void Main(string[] args)
{
//SingletionServiceTest();
//TransientServiceTest();
ScoreServiceTest();
Console.ReadKey();
}
private static void ScoreServiceTest()
{
ServiceCollection services = new ServiceCollection();
services.AddScoped<TestServicelmpl>();
TestServicelmpl tt;
using (ServiceProvider sp = services.BuildServiceProvider())
{
using (IServiceScope scope1 = sp.CreateScope())
{
TestServicelmpl testServicelmpl = scope1.ServiceProvider.GetService<TestServicelmpl>();
TestServicelmpl testServicelmpl2 = scope1.ServiceProvider.GetService<TestServicelmpl>();
testServicelmpl.Name = "ouou";
bool isEqual = ReferenceEquals(testServicelmpl, testServicelmpl2);
tt = testServicelmpl;
}
using (IServiceScope scope2 = sp.CreateScope())
{
TestServicelmpl testServicelmpl = scope2.ServiceProvider.GetService<TestServicelmpl>();
TestServicelmpl testServicelmpl2 = scope2.ServiceProvider.GetService<TestServicelmpl>();
testServicelmpl.Name = "kk";
bool isEqual = ReferenceEquals(testServicelmpl, testServicelmpl2);
isEqual = ReferenceEquals(testServicelmpl, tt);
}
}
}
static void SingletionServiceTest()
{
ServiceCollection services = new ServiceCollection();
services.AddSingleton<TestServicelmpl>();
using (ServiceProvider sp = services.BuildServiceProvider())
{
TestServicelmpl testServicelmpl = sp.GetService<TestServicelmpl>();
TestServicelmpl testServicelmpl2 = sp.GetService<TestServicelmpl>();
bool isEqual = ReferenceEquals(testServicelmpl, testServicelmpl2);
testServicelmpl.Name = "ouou";
testServicelmpl.SayHi();
testServicelmpl.Name = "kk";
testServicelmpl2.SayHi();
}
}
static void TransientServiceTest()
{
ServiceCollection services = new ServiceCollection();
services.AddTransient<TestServicelmpl>();
using (ServiceProvider sp = services.BuildServiceProvider())
{
TestServicelmpl testServicelmpl = sp.GetService<TestServicelmpl>();
TestServicelmpl testServicelmpl2 = sp.GetService<TestServicelmpl>();
bool isEqual = ReferenceEquals(testServicelmpl, testServicelmpl2);
testServicelmpl.Name = "ouou";
testServicelmpl.SayHi();
testServicelmpl.Name = "kk";
testServicelmpl2.SayHi();
}
}
}
}