問題
如何在ASP.NET Core 2.0向中介軟體傳入初始引數?
答案
在一個空專案中,建立一個POCO(Plain Old CLR Object)來儲存中介軟體所需的引數:
public class GreetingOptions { public string GreetAt { get; set; } public string GreetTo { get; set; } }
新增一箇中介軟體:
public class GreetingMiddleware { private readonly RequestDelegate _next; private readonly GreetingOptions _options; public GreetingMiddleware(RequestDelegate next, GreetingOptions options) { _next = next; _options = options; } public async Task Invoke(HttpContext context) { var message = $"Good {_options.GreetAt} {_options.GreetTo}"; await context.Response.WriteAsync(message); } }
答案1:例項型別
新增一個擴充套件方法來配置中介軟體:
public static IApplicationBuilder UseGreetingMiddleware(this IApplicationBuilder app, GreetingOptions options) { return app.UseMiddleware<GreetingMiddleware>(options); }
使用中介軟體:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseGreetingMiddleware(new GreetingOptions { GreetAt = "Morning", GreetTo = "Tahir" }); }
答案2:函式型別
新增一個擴充套件方法來配置中介軟體:
public static IApplicationBuilder UseGreetingMiddlewareAction(this IApplicationBuilder app, Action<GreetingOptions> optionsAction) { var options = new GreetingOptions(); optionsAction(options); return app.UseMiddleware<GreetingMiddleware>(options); }
使用中介軟體:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseGreetingMiddlewareAction(options => { options.GreetAt = "Morning"; options.GreetTo = "Tahir"; }); }
上述兩種方法結果一致。
執行,此時頁面顯示:
討論
之前我們曾討論過,在單獨的類中定義中介軟體並使用擴充套件方法將其新增到請求管道中是最佳實踐。我們也可能需要向中介軟體傳入引數,透過對ASP.NET Core原始碼以及其他線上示例的學習,我總結出來上面兩種模式。
上述的兩種解決方法都非常直觀。我們將引數封裝到一個POCO類中,然後建立一個擴充套件方法來接受下面的引數:
1. POCO例項
2. 需要呼叫的函式(在函式內設定POCO)
注:POCO例項透過建構函式傳入中介軟體。UseMiddleware()方法接收可變引數params object[],並將這些引數傳入中介軟體建構函式。
配置服務
這些模式也能用於向服務容器中新增服務例項。為了便於說明,我們先新增一個服務:
public interface IMessageService { string FormatMessage(string message); } public class MessageService : IMessageService { private readonly GreetingOptions _options; public MessageService(GreetingOptions options) { _options = options; } public string FormatMessage(string message) { return $"Good {_options.GreetAt} {_options.GreetTo} - {message}"; } }
新增如下任一個擴充套件方法來配置服務:
public static IServiceCollection AddMessageService(this IServiceCollection services, GreetingOptions options) { return services.AddScoped<IMessageService>(factory => new MessageService(options)); } public static IServiceCollection AddMessageServiceAction(this IServiceCollection services, Action<GreetingOptions> optionsAction) { var options = new GreetingOptions(); optionsAction(options); return services.AddScoped<IMessageService>(factory => new MessageService(options)); }
在Configure()中使用此服務:
public void ConfigureServices(IServiceCollection services) { services.AddMessageService(new GreetingOptions { GreetAt = "Morning", GreetTo = "Tahir" }); services.AddMessageServiceAction(options => { options.GreetAt = "Morning"; options.GreetTo = "Tahir"; }); }
因為ConfigureServices()先於Configure()執行,因此我們可以直接在Configure()注入此服務:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IMessageService msg) { app.Run(async (context) => { await context.Response.WriteAsync(msg.FormatMessage("by sanshi")); }); }
執行,此時頁面顯示:
原始碼下載
原文:https://tahirnaushad.com/2017/08/29/passing-parameters-to-middleware-in-asp-net-core-2-0/