[英]Using middleware config from extension methods in ASP.NET Core
我已經開發了一個ASP.NET Core中間件。 為了簡化問題,我在本文中簡化了中間件。
中間件在Startup.cs
配置如下:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseMyMiddleware(42);
...
}
整數( 42
)存儲在中間件實例中,一切都很好。
現在,我想創建一些輔助方法作為擴展方法:
public static int Add(this int i)
{
return i + TODO;
}
我想要將i
的值添加到發送到中間件的值( 42
)的方法。
目前,我已經將值42
保存在中間件內部的公共static var中,並通過我的擴展方法進行訪問:
public static int Add(this int i)
{
return i + MyMiddleware.Value;
}
由於種種原因,我不喜歡這種解決方案。 如何更好地解決此問題的任何想法將受到高度贊賞。
通常,這不適用於擴展方法。 擴展方法是靜態的,因此只能訪問其他靜態成員。 但是, ASP.NET Core 在設計上不使用任何靜態變量,並且廣泛使用依賴項注入來管理對象的生存期和訪問依賴項。
因此,通常,正確的方法是將擴展方法移到某種非靜態幫助器對象中,然后可以將其插入需要訪問它的位置。 當然,這將不允許您在需要的地方輕松調用它,而需要您明確依賴它(這是依賴注入的要點之一)。
話雖如此,您的明確情況有些不同。 從鏈接的pull request中可以看到,您的擴展方法看起來像這樣(請注意,我在這里結合了兩種方法以使其清晰可見):
public static async Task ShipAsync(this Exception exception, HttpContext context)
{
await MessageShipper.ShipAsync(
ElmahIoMiddleware.ApiKey.AssertApiKeyInMiddleware(),
ElmahIoMiddleware.LogId.AssertLogIdInMiddleware(),
exception.Message, context, new ElmahIoSettings(), exception);
}
為什么這么重要? 因為您正在傳遞HttpContext
。 HTTP上下文使我們可以訪問依賴項注入。 因此,我們實際上可以從依賴項注入容器中解決問題:
public static async Task ShipAsync(this Exception exception, HttpContext context)
{
var elmahIoConfig = context.RequestServices.GetService<ElmahIoConfiguration>();
await MessageShipper.ShipAsync(
elmahIoConfig.ApiKey,
elmahIoConfig.LogId,
exception.Message, context, new ElmahIoSettings(), exception);
}
現在,您只需要確保注冊中間件時就可以正確填充ElmahIoConfiguration
。 請注意,在這里我不要求中間件實例,因為中間件通常不向依賴項注入注冊。 引入一個單獨的對象更有意義,然后您可以將該對象注入中間件並在那里進行初始化。
在您的情況下,您實際上應該將中間件配置移到應用程序設置中,並使用IOptions<>
模式在ConfigureServices
級別對其進行ConfigureServices
。 在ASP.NET Core 2中將中間件添加到“ Configure
的管道時進行Configure
實際上不再是一種常見的模式。
您為什么不使用appsettings.json來存儲此信息,然后使用內置的DI將其注入到中間件中?
appsettings.json
{
"MiddlewareConfiguration":
{
"MiddlewareValue":42,
}
}
Startup.cs
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.Configure<MiddlewareConfiguration>(configuration.GetSection("MiddlewareConfiguration"));
}
MiddlewareConfiguration.cs
public class MiddlewareConfiguration
{
public int MiddlewareValue { get; set; }
}
然后可以將其注入到中間件中,例如:
public async Task Invoke(HttpContext context, IOptions<MiddlewareConfiguration> config)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.