NET8中增加的简单适用的DI扩展库Microsoft.Extensions.DependencyInjection.AutoActivation

net8,di,microsoft,extensions,dependencyinjection,autoactivation · 浏览次数 : 14

小编点评

**概述** 本文主要讨论单例模式与AutoActivation扩展库在ASP.NET Core中的应用及其优势。 **单例模式** 单例模式是一种常见的设计模式,它确保一个类在整个应用程序中只有一个实例。这种模式下,该类的构造函数不可被外部访问,从而避免了资源的浪费和多线程环境下的问题。当首次使用时,它会创建实例;首次使用后,实例将保持活动状态直至程序关闭。 **AutoActivation扩展库** 在ASP.NET Core中,Microsoft.Extensions.DependencyInjection这个库提供了一种名为AutoActivation的功能,使得在系统启动时可以实例化已注册的单例,而不是在每次请求时实例化。这种方法可以显著提高性能,尤其是在高并发的场景下。通过使用AutoActivation,开发者可以在注册单例时不立即实例化,而是在Auto激活HostedService启动时实例化它们。 **Auto激活HostedService源码分析** 本文提供了AutoActivationHostedService的源码,并对其进行了简要分析。该类负责在系统启动时从IServiceProvider获取所有已注册为AutoActivation的单例,并在启动过程中将这些实例注入到需要的组件中。 **使用场景** 本文给出了一个示例,其中在Biwen.Settings中添加了对JSON配置监听的功能。由于引入了AutoActivation扩展库,因此可以通过构造函数代替原有的Start方法,从而简化了代码逻辑并解决SLA问题。这种应用方式可以作为SLA保障的另一种补充手段。 **总结** 本文通过对单例模式与AutoActivation扩展库的介绍,展示了如何在ASP.NET Core中优化实例化过程以提升性能,并提供了对Auto_activationHostedService源码的分析和示例应用,最后总结了这种技术在ASP.NET Core中的重要作用和潜在应用。

正文

这个库提供了在启动期间实例化已注册的单例,而不是在首次使用它时实例化。

单例通常在首次使用时创建,这可能会导致响应传入请求的延迟高于平时。在注册时创建实例有助于防止第一次Request请求的SLA

以往我们要在注册的时候启动单例可能会这样写:

//注册:
services.AddSingleton<FileChangeNotifier>();
//初始化
using var scope = services.BuildServiceProvider().CreateScope();
scope.ServiceProvider.GetRequiredService<FileChangeNotifier>();

但是借助Microsoft.Extensions.DependencyInjection.AutoActivation 我们的写法就特别的简单了:

//注册服务,并直接实例化
services.AddActivatedSingleton<FileChangeNotifier>();

AutoActivation扩展库其实相当简单,内部实现了一个AutoActivationHostedService的 HostedService,当系统启动的时候就从IServiceProvider中取到所有注册为AutoActivation的单例,下面是他的源码:

internal sealed class AutoActivationHostedService : IHostedService
{
    private readonly AutoActivatorOptions _options;
    private readonly IServiceProvider _provider;

    public AutoActivationHostedService(IServiceProvider provider, IOptions<AutoActivatorOptions> options)
    {
        _provider = provider;
        _options = Throw.IfMemberNull(options, options.Value);
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        foreach (var singleton in _options.AutoActivators)
        {
            _ = _provider.GetRequiredService(singleton);
        }

        foreach (var (serviceType, serviceKey) in _options.KeyedAutoActivators)
        {
            _ = _provider.GetRequiredKeyedService(serviceType, serviceKey);
        }

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}

当然提供的扩展不限于AddActivatedSingleton<T>一个,还有如下的扩展方法:

public static IServiceCollection ActivateSingleton<TService>(this IServiceCollection services)
public static IServiceCollection ActivateSingleton(this IServiceCollection services, Type serviceType)
public static IServiceCollection AddActivatedSingleton<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory)
public static IServiceCollection AddActivatedSingleton<TService, TImplementation>(this IServiceCollection services)
public static IServiceCollection AddActivatedSingleton<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory)
public static IServiceCollection AddActivatedSingleton<TService>(this IServiceCollection services)
public static IServiceCollection AddActivatedSingleton(this IServiceCollection services, Type serviceType)
public static IServiceCollection AddActivatedSingleton(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory)
public static IServiceCollection AddActivatedSingleton(this IServiceCollection services, Type serviceType, Type implementationType)
public static void TryAddActivatedSingleton(this IServiceCollection services, Type serviceType)
public static void TryAddActivatedSingleton(this IServiceCollection services, Type serviceType, Type implementationType)
public static void TryAddActivatedSingleton(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory)
public static void TryAddActivatedSingleton<TService>(this IServiceCollection services)
public static void TryAddActivatedSingleton<TService, TImplementation>(this IServiceCollection services)
public static void TryAddActivatedSingleton<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory)
 
public static IServiceCollection ActivateKeyedSingleton<TService>(this IServiceCollection services, object? serviceKey)
public static IServiceCollection ActivateKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey)
public static IServiceCollection AddActivatedKeyedSingleton<TService, TImplementation>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object?, TImplementation> implementationFactory)
public static IServiceCollection AddActivatedKeyedSingleton<TService, TImplementation>(this IServiceCollection services, object? serviceKey)
public static IServiceCollection AddActivatedKeyedSingleton<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object?, TService> implementationFactory)
public static IServiceCollection AddActivatedKeyedSingleton<TService>(this IServiceCollection services, object? serviceKey)
public static IServiceCollection AddActivatedKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey)
public static IServiceCollection AddActivatedKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey, Func<IServiceProvider, object?, object> implementationFactory)
public static IServiceCollection AddActivatedKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey, Type implementationType)
public static void TryAddActivatedKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey)
public static void TryAddActivatedKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey, Type implementationType)
public static void TryAddActivatedKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey, Func<IServiceProvider, object?, object> implementationFactory)
public static void TryAddActivatedKeyedSingleton<TService>(this IServiceCollection services, object? serviceKey)
public static void TryAddActivatedKeyedSingleton<TService, TImplementation>(this IServiceCollection services, object? serviceKey)
public static void TryAddActivatedKeyedSingleton<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object?, TService> implementationFactory)

最近我在Biwen.Settings添加了对JSON配置监听的功能,有这方面的需求,最初是有一个Start方法,也就是启动系统的时候获取服务然后调用Start方法,如果使用了AutoActivation 那Start的方法体可以直接使用构造函数替代,这个也是除了开头解决SLA以外的一个用例吧

有任何不足的地方欢迎小伙伴们留言指正

与NET8中增加的简单适用的DI扩展库Microsoft.Extensions.DependencyInjection.AutoActivation相似的内容:

NET8中增加的简单适用的DI扩展库Microsoft.Extensions.DependencyInjection.AutoActivation

这个库提供了在启动期间实例化已注册的单例,而不是在首次使用它时实例化。 单例通常在首次使用时创建,这可能会导致响应传入请求的延迟高于平时。在注册时创建实例有助于防止第一次Request请求的SLA 以往我们要在注册的时候启动单例可能会这样写: //注册: services.AddSingleton<

Asp-Net-Core开发笔记:给SwaggerUI加上登录保护功能

前言 在 SwaggerUI 中加入登录验证,是我很早前就做过的,不过之前的做法总感觉有点硬编码,最近 .Net8 增加了一个新特性:调用 MapSwagger().RequireAuthorization 来保护 Swagger UI ,但官方的这个功能又像半成品一样,只能使用 postman c

ASP.NET Core 8 预览版 4的重大更新

最新版本的 .NET 8 预览版 4 对 ASP.NET Core 进行了重大改进。值得注意的增强功能包括 Blazor 的流式呈现和表单处理、在最小 API 中扩展对表单绑定的支持、用于提高性能的NativeAOT 编译、使用标识 API 终结点增强的身份验证和授权,以及添加用于应用程序监视的指标

.NET8中的Microsoft.Extensions.Http.Resilience库

接上一篇,https://www.cnblogs.com/vipwan/p/18129361 借助Aspire中新增的Microsoft.Extensions.ServiceDiscovery库,我们可以很容易的做到服务发现,那么服务节点的熔断限流以及重试等弹性机制.NET是怎么处理的呢? 比如下图

【.NET8】访问私有成员新姿势UnsafeAccessor(下)

前言 书接上回,我们讨论了在.NET8中新增的UnsafeAccessor,并且通过UnsafeAccessor访问了私有成员,这极大的方便了我们代码的编写,当然也聊到了它当前存在的一些局限性,那么它的性能到底如何?我们今天就来实际测试一下。 测试代码 话不多说,直接上代码,本次测试代码如下: us

造轮子之asp.net core identity

在前面我们完成了应用最基础的功能支持以及数据库配置,接下来就是我们的用户角色登录等功能了,在asp.net core中原生Identity可以让我们快速完成这个功能的开发,在.NET8中,asp.net core identity支持了WebApi的注册登录。这让我们在WebApi中可以更爽快的使用

.Net8 AddKeyedScoped键值key注册服务异常

异常描述:This service descriptor is keyed. Your service provider may not support keyed services. 场景:.Net8 WebAPI应用程序中使用AutoFac替代了默认的DI容器 当使用键值注册服务后: build

.NET8 Identity Register

分享给需要帮助的人:记一次 IdentityAPI 中注册的源码解读:设置用户账户为未验证状态,以及除此之外更安全的做法: 延迟用户创建。包含了对优缺点的说明,以及适用场景。 在ASP.NET 8 Identity 中注册API的源码如下: routeGroup.MapPost("/register

【.NET 8】ASP.NET Core计划 - 支持更完善的AOT发布

.NET7.0刚发布不久,.NET社区开始了.NET8.0的开发,重心重新回到了新功能的迭代。 我们知道在.NET7.0中一个令人激动的特新就是支持了NativeAOT,我们可以通过NativeAOT生成本机程序,由于无需JIT编译,所以无需安装.NET Runtime,也进一步的提升了.程序的启动

本计划在 .NET 8 中推出的 WASI 推迟到 .NET 9

本计划在 .NET 8 中推出的 WASI 已推迟到 .NET 9,请参阅 Github 上的 WASI 跟踪问题。 在.NET 8 Preview 4 开始支持生成与 WASI 兼容的 .wasm 文件,使用独立的 WebAssembly 运行时 Wasmtime CLI[1] 运行该文件。去年的