Asp.net core 2.0
== 原文地址已不能訪問,停止本系列更新==
問題
如何傳遞參數到中間件在構建Asp.net core的時候
解決方案
在空項目中添加POCO類去為中間件持有參數
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)
{
this.next = next;
this.options = options;
}
public async Task Invoke(
HttpContext context)
{
var message = $"Good {this.options.GreetAt} {this.options.GreetTo}";
await context.Response.WriteAsync(message);
}
}
解決方案 A: 實例類型
添加擴增類型去配置中間件
public static IApplicationBuilder UseGreeting(
this IApplicationBuilder app, GreetingOptions options)
{
return app.UseMiddleware<GreetingMiddleware>(options);
}
配置中間件
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env)
{
app.UseGreeting(new GreetingOptions
{
GreetAt = "Morning",
GreetTo = "Tahir"
});
}
解決方案 B: 函數式類型
添加擴增類型去配置中間件
public static IApplicationBuilder UseGreeting(
this IApplicationBuilder app, Action<GreetingOptions> configureOptions)
{
var options = new GreetingOptions();
configureOptions(options);
return app.UseMiddleware<GreetingMiddleware>(options);
}
配置 中間件
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env)
{
app.UseGreeting(options =>
{
options.GreetAt = "Morning";
options.GreetTo = "Tahir";
});
}
討論
在上一篇文章中有討論到定義中間件添加到管道并使用擴增方法是最佳實踐,我們可能需要傳遞參數通過中間件,當我深入研究aspnet core源碼和其他例子時發現有兩種模式,
這兩種模式可以參考上面的解決方案A和解決方案B, 我們包裝參數在POCO的類里,創建一個擴增方法傳遞他們
- POCO 實例
- 調用函數, 設置 POCO.
注:POCO是傳遞到中間件的構造函數。 UseMiddleware()
把 params object[]
作為參數傳到中間件的構造函數中。
配置服務
這種模式會用到依賴注入到服務容器,演示代碼
public class MessageService : IMessageService
{
private readonly MessageOptions options;
public MessageService(MessageOptions options)
{
this.options = options;
}
public string FormatMessage(string message)
{
// use options
return this.options.Format == MessageFormat.None ? message :
this.options.Format == MessageFormat.Upper ? message.ToUpper() :
message.ToLower();
}
}
添加這些擴增方法到配置服務:
// Instance Type
public static IServiceCollection AddMessageFormatter(
this IServiceCollection services, MessageOptions options)
{
return services.AddScoped<IMessageService>(factory =>
{
return new MessageService(options);
});
}
// Function Type
public static IServiceCollection AddMessageFormatter(
this IServiceCollection services, Action<MessageOptions> configureOptions)
{
var options = new MessageOptions();
configureOptions(options);
return services.AddScoped<IMessageService>(factory =>
{
return new MessageService(options);
});
}
用下面的代碼配置服務
// Instance Type
public void ConfigureServices(
IServiceCollection services)
{
services.AddMessageFormatter(new MessageOptions
{
Format = MessageFormat.Lower
});
}
// Function Type
public void ConfigureServices(
IServiceCollection services)
{
services.AddMessageFormatter(options =>
{
options.Format = MessageFormat.Lower;
});
}
Source Code
GitHub: https://github.com/TahirNaushad/Fiver.Asp.Middleware.Options