如何在 ASP.NET Core 中使控制器作用域或单例而不是瞬态?

Posted

技术标签:

【中文标题】如何在 ASP.NET Core 中使控制器作用域或单例而不是瞬态?【英文标题】:How to make controllers scoped or singleton instead of transient in ASP.NET Core? 【发布时间】:2020-10-28 15:17:07 【问题描述】:

我现在默认情况下,控制器注册到具有瞬态生命周期的默认 DI 容器。

如果我想用不同的生命周期注册它们,我该怎么做?

我想知道仅出于教育目的,以便更好地了解 DI 容器的控制器类型管理。

【问题讨论】:

【参考方案1】:

我现在默认情况下,控制器注册到具有瞬态生命周期的默认 DI 容器。

默认情况下,控制器没有注册。默认的IControllerActivator 在没有显式注册的情况下创建了该类型。

如果你想改变这个,你应该打电话:

services.AddMvc().AddControllersAsServices();

这将确保控制器已注册,并且原始 IControllerActivator 被替换为从 DI 容器解析控制器的 (ServiceBasedControllerActivator)。

AddControllersAsServices,不幸的是,总是使用 Transient 生活方式注册控制器,并且无法覆盖该行为。所以你必须重新实现AddControllersAsServices

public static IMvcBuilder AddControllersAsServices(
    this IMvcBuilder builder, ServiceLifetime lifetime)

    var feature = new ControllerFeature();
    builder.PartManager.PopulateFeature(feature);

    foreach (var controller in feature.Controllers.Select(c => c.AsType()))
    
        builder.Services.Add(
            ServiceDescriptor.Describe(controller, controller, lifetime));
    

    builder.Services.Replace(ServiceDescriptor
        .Transient<IControllerActivator, ServiceBasedControllerActivator>());

    return builder;

这种新的扩展方法可以如下使用:

services.AddMvc().AddControllersAsServices(ServiceLifetime.Singleton);

【讨论】:

以上是关于如何在 ASP.NET Core 中使控制器作用域或单例而不是瞬态?的主要内容,如果未能解决你的问题,请参考以下文章

asp.net signalr core 中的跨域请求不起作用?

ASP.NET CORE2.2在中间件内使用有作用域的服务

Asp.Net Core 服务生命周期

如何在ASP NET Core中实现CORS跨域

无法在 ASP.NET Core 1.0 中启用跨域请求 (CORS)

Asp.Net Core - 在文本区域中显示字符串列表值?