91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ASP.NET?Core?MVC如何創建控制器與依賴注入

發布時間:2022-02-21 14:43:06 來源:億速云 閱讀:202 作者:iii 欄目:開發技術

這篇文章主要介紹“ASP.NET Core MVC如何創建控制器與依賴注入”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“ASP.NET Core MVC如何創建控制器與依賴注入”文章能幫助大家解決問題。

默認的IControllerActivator

在 ASP.NET Core 中,當 MVC 中間件接收到請求時,通過路由選擇要執行的控制器和操作方法。為了實際的執行操作, MVC 中間件必須創建所選控制器的實例。

創建控制器的過程依賴眾多不同的提供者和工廠類,但最終是由實現IControllerActivator接口的實例來決定的。實現類只需要實現兩個方法:

public interface IControllerActivator  
{
    object Create(ControllerContext context);
    void Release(ControllerContext context, object controller);
}

如您所見,該IControllerActivator.Create方法傳遞了用于創建控制器的ControllerContext實例。控制器的創建方式取決于具體的實現。

眾所周知,ASP.NET Core 使用的是DefaultControllerActivator,它通過TypeActivatorCache來創建控制器。TypeActivatorCache通過調用類的構造函數,并試圖從 DI 容器中解析構造函數所需參數的實例。

有一點很重要,DefaultControllerActivator 不會試圖從 DI 容器中解析控制器的實例,只會解析控制器的依賴項。

DefaultControllerActivator 示例

為了演示這個行為,我創建了一個簡單的 MVC 應用程序,包括一個單一的服務和一個控制器。服務實例有一個name屬性,它通過構造函數來設置。默認情況下,它使用"default"作為默認值。

public class TestService  
{
    public TestService(string name = "default")
    {
        Name = name;
    }

    public string Name { get; }
}

在應用程序中HomeController依賴于TestService,并返回Name屬性的值:

public class HomeController : Controller  
{
    private readonly TestService _testService;
    public HomeController(TestService testService)
    {
        _testService = testService;
    }

    public string Index()
    {
        return "TestService.Name: " + _testService.Name;
    }
}

還有一塊代碼在Startup文件中。在這里我將TestService注冊在 DI 容器中作為范圍內服務,并設置 MVC 中間件和服務:

public class Startup  
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        services.AddScoped<TestService>();
        services.AddTransient(ctx =>
            new HomeController(new TestService("Non-default value")));
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMvcWithDefaultRoute();
    }
}

您會注意到,我定義了一個工廠方法用于創建HomeController的實例。將HomeController類型注冊到 DI 容器中,并且在TestService實例中傳遞自定義Name屬性。

如果您運行應用程序,您會看到什么結果?

ASP.NET?Core?MVC如何創建控制器與依賴注入

您可以看到,該TestService.Name屬性使用的是默認值,表示TestService實例是直接從 DI 容器中獲取的,直接忽略了創建HomeController的工廠方法。

這很容易理解,當您通過DefaultControllerActivator創建控制器時,它不會從DI容器中創建HomeController實例,只會解析構造函數的依賴項。

大多數情況下,使用DefaultControllerActivator是一個不錯的選擇,但有時您可能希望直接通過 DI 容器來創建控制器,比如您希望使用具有攔截器或裝飾器等功能的第三方容器。

幸運的是,MVC 框架包含了一個這樣的IControllerActivator實現,并提供了一種非常方便的擴展方法來啟用它。

ServiceBasedControllerActivator

如您所見,DefaultControllerActivator使用TypeActivatorCache來創建控制器,MVC還包括另一個實現,稱為 ServiceBasedControllerActivator,它是直接從 DI 容器中獲取控制器。它的實現非常簡單:

public class ServiceBasedControllerActivator : IControllerActivator  
{
    public object Create(ControllerContext actionContext)
    {
        var controllerType = actionContext.ActionDescriptor.ControllerTypeInfo.AsType();

        return actionContext.HttpContext.RequestServices.GetRequiredService(controllerType);
    }

    public virtual void Release(ControllerContext context, object controller)
    {
    }
}

當您將 MVC 服務添加到應用程序時,可以使用AddControllersAsServices()擴展方法配置基于 DI 的激活器:

public class Startup  
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
                .AddControllersAsServices();

        services.AddScoped<TestService>();
        services.AddTransient(ctx =>
            new HomeController(new TestService("Non-default value")));
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMvcWithDefaultRoute();
    }
}

通過上面的代碼,點擊主頁將通過 DI 容器來創建一個控制器。由于我們已經注冊了一個創建HomeController的工廠方法,我們自定義TestService配置將被保留,使用替換后的Name屬性:

ASP.NET?Core?MVC如何創建控制器與依賴注入

AddControllersAsServices方法實現了兩件事情 - 它將您應用程序中的所有控制器注冊到 DI 容器(如果尚未注冊),并將IControllerActivator注冊為ServiceBasedControllerActivator

public static IMvcBuilder AddControllersAsServices(this IMvcBuilder builder)  
{
    var feature = new ControllerFeature();
    builder.PartManager.PopulateFeature(feature);

    foreach (var controller in feature.Controllers.Select(c => c.AsType()))
    {
        builder.Services.TryAddTransient(controller, controller);
    }

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

    return builder;
}

如果需要做一些更復雜的事情,您可以隨時實現自己IControllerActivator;不過我找不到任何理由,這兩點實現還不能滿足您的需求!

關于“ASP.NET Core MVC如何創建控制器與依賴注入”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

邢台市| 屏东县| 樟树市| 图片| 九龙县| 阿勒泰市| 黑水县| 竹溪县| 溧阳市| 磴口县| 舒兰市| 清镇市| 长治县| 巨野县| 富蕴县| 牡丹江市| 县级市| 根河市| 长子县| 葫芦岛市| 吴江市| 密山市| 磐石市| 长岭县| 汾阳市| 神池县| 溧水县| 白水县| 大足县| 姜堰市| 尉犁县| 临高县| 安陆市| 阿拉尔市| 晋江市| 灵丘县| 白玉县| 淳安县| 鹤庆县| 涡阳县| 衡山县|