簡體   English   中英

如何在C#WebApi中將依賴項注入靜態框架類中

[英]How to inject a dependency into a static framework class in C# WebApi

在我的.NET 4.6.1 WebApi項目的WebApiConfig.cs類中,僅當web.config中的應用程序設置設置為true時,我才想啟用CORS。 我通常使用AppSettings類讀取web.config AppSettings,該類將值從字符串轉換為更合適的數據類型。 我聲明一個IAppSettings接口,並將類型注冊到我正在使用的Autofac DI容器中。

但是,在這種情況下,WebApiConfig是靜態類,其Register方法的調用方式如下:GlobalConfiguration.Configure(WebApiConfig.Register); 我無法更改GlobalConfiguration.Configure類的簽名,因此我看不到如何注入IAppSettings對象以使其在Register方法中可訪問。 當然,我可以訪問ConfigurationManager,但這似乎很麻煩。 當然,我也可以將AppSettings聲明為靜態類,但這會使單元測試變得困難。 有沒有更清潔的方法可以做到這一點?

這是相關的代碼-ConfigurationManager行是我要替換為對appSettings類的調用的行:

    public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        if (System.Configuration.ConfigurationManager.AppSettings.Get("IsCorsEnabled", false))
        {
            config.EnableCors();
        }
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

非常感謝您的協助!

假設您有一個這樣的界面用於您的應用程序設置(多種):

public interface IAppSettings
{
    T Get<T>(string name);
}

這是默認的實現,它只是圍繞ConfigurationManager

public class DefaultAppSettings : IAppSettings
{
    public T Get<T>(string name)
    {
        return (T)Convert.ChangeType(ConfigurationManager.AppSettings[name], typeof(T));
    }
}

如果然后定義這樣的類:

public static class CurrentAppSettings
{
    public static Func<IAppSettings> Instance = () => new DefaultAppSettings();
}

您可以在注冊方法中使用此方法:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        if (CurrentAppSettings.Instance().Get<bool>("IsCorsEnabled"))
        {
            config.EnableCors();
        }
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

如果要注入其他實現,例如在測試中,只需將CurrentAppSettings實例設置為其他值即可:

[Test]
public void SomeTest()
{
    CurrentAppSettings.Instance = () => new SimpleKeyValueAppSettings(new Dictionary<string, string>());

    // ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM