ZetCode

ASP.NET ServiceProvider

最后修改于 2025 年 4 月 3 日

在本文中,我们将探讨ASP.NET 8中的ServiceProvider。这个核心组件负责管理应用程序中的依赖注入和服务生命周期。

ASP.NET内置的依赖注入系统使用ServiceProvider来解析和管理服务。这对于编写模块化、可测试的应用程序至关重要。

基本定义

ASP.NET中的ServiceProvider是管理已注册服务的容器。它实现了IServiceProvider接口并处理服务解析。

服务以特定的生命周期进行注册:瞬态(transient)、作用域(scoped)或单例(singleton)。ServiceProvider根据这些生命周期创建和处置服务。

瞬态服务每次请求时都会创建。作用域服务每个客户端请求只创建一个实例。单例服务只创建一次并重复使用。

ASP.NET ServiceProvider示例

以下示例演示了ServiceProvider在不同服务生命周期和服务解析中的用法。

Program.cs
var builder = WebApplication.CreateBuilder(args);

// Register services with different lifetimes
builder.Services.AddTransient<ITransientService, TransientService>();
builder.Services.AddScoped<IScopedService, ScopedService>();
builder.Services.AddSingleton<ISingletonService, SingletonService>();

var app = builder.Build();

app.MapGet("/", (HttpContext context) =>
{
    var serviceProvider = context.RequestServices;
    
    var transient1 = serviceProvider.GetRequiredService<ITransientService>();
    var transient2 = serviceProvider.GetRequiredService<ITransientService>();
    
    var scoped1 = serviceProvider.GetRequiredService<IScopedService>();
    var scoped2 = serviceProvider.GetRequiredService<IScopedService>();
    
    var singleton1 = serviceProvider.GetRequiredService<ISingletonService>();
    var singleton2 = serviceProvider.GetRequiredService<ISingletonService>();
    
    return Results.Ok(new
    {
        TransientSame = transient1.Id == transient2.Id,
        ScopedSame = scoped1.Id == scoped2.Id,
        SingletonSame = singleton1.Id == singleton2.Id,
        Transient1 = transient1.Id,
        Transient2 = transient2.Id,
        Scoped1 = scoped1.Id,
        Scoped2 = scoped2.Id,
        Singleton1 = singleton1.Id,
        Singleton2 = singleton2.Id
    });
});

app.Run();

这会设置一个ASP.NET应用程序,其中三个服务以不同的生命周期注册。该终结点演示了ServiceProvider如何解析这些服务。

Services/ServiceDefinitions.cs
public interface ITransientService
{
    Guid Id { get; }
}

public interface IScopedService
{
    Guid Id { get; }
}

public interface ISingletonService
{
    Guid Id { get; }
}

public class TransientService : ITransientService
{
    public Guid Id { get; } = Guid.NewGuid();
}

public class ScopedService : IScopedService
{
    public Guid Id { get; } = Guid.NewGuid();
}

public class SingletonService : ISingletonService
{
    public Guid Id { get; } = Guid.NewGuid();
}

这定义了服务接口和实现。每个服务都有一个Guid Id属性,以展示不同生命周期下的实例创建行为。

当你调用该终结点时,你会发现瞬态服务在每次解析时都会获得新的实例。作用域服务在每个请求中重用相同的实例。单例服务在应用程序的整个生命周期内维护一个实例。

如果服务未注册,GetRequiredService方法将抛出异常。对于可选服务,请使用GetService,它会为未注册的服务返回null。

来源

Microsoft ASP.NET 依赖注入文档

在本文中,我们探讨了ASP.NET 8中的ServiceProvider。这个强大的组件是ASP.NET依赖注入系统的基础。

作者

我叫Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。我自2007年以来一直在撰写编程文章。迄今为止,我已撰写了1400多篇文章和8本电子书。我在教授编程方面拥有超过十年的经验。

列出所有 ASP.NET 教程