標籤:
本節介紹的是Microsoft.AspNet.Localization工程。該工程是運行在Asp.net 5環境中的運行時多語言設定。
ASP.net 5中介軟體技術
在新的Asp.net 5中,可以將組件組冊到asp.net環境中。註冊是通過介面IApplicationBuilder的擴充方法實現的。
public static IApplicationBuilder UseMiddleware(this IApplicationBuilder builder, Type middleware, params object[] args)
[該擴充方法通過可變參數args傳遞所需要的參數以及外的RequestDelegate(delegate Task RequestDelegate(HttpContext context))類型(系統會在內部給該型別參數賦值)。建立Type(middleware)類型執行個體。之後調用Type(middleware)的Invoke方法,不過和建構函式不同的是,當Invoke方法參數大於一個時,參數全部來自於以來注入,而不是args]
通過IApplicationBuilder注入的中介軟體,必須有一個方法是Invoke,Invoke方法的參數是可變參數,長度不受限制,系統會從asp.net的反轉控制中擷取參數;系統之後會調用該Invoke方法。[此處有疑問:為啥不定義成包含invoke方法的介面,更加物件導向]
我們在Microsoft.AspNet.Localization工程中可以找到倆個類:
- IApplicationBuilderExtensions 中間註冊方法,在Microsoft.AspNet.Localization工程中的實現。
- RequestLocalizationMiddleware 中介軟體類,是Microsoft.AspNet.Localization的入口。
public static class IApplicationBuilderExtensions { public static IApplicationBuilder UseRequestLocalization([NotNull] this IApplicationBuilder builder) { var options = new RequestLocalizationOptions(); return UseRequestLocalization(builder, options); } public static IApplicationBuilder UseRequestLocalization( [NotNull] this IApplicationBuilder builder, [NotNull] RequestLocalizationOptions options) => builder.UseMiddleware<RequestLocalizationMiddleware>(options); }
IApplicationBuilderExtensions
public class RequestLocalizationMiddleware { private readonly RequestDelegate _next; private readonly RequestLocalizationOptions _options; public RequestLocalizationMiddleware([NotNull] RequestDelegate next, [NotNull] RequestLocalizationOptions options) { _next = next; _options = options; } public async Task Invoke([NotNull] HttpContext context) { var requestCulture = _options.DefaultRequestCulture ?? new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture); IRequestCultureProvider winningProvider = null; if (_options.RequestCultureProviders != null) { foreach (var provider in _options.RequestCultureProviders) { var result = await provider.DetermineRequestCulture(context); if (result != null) { requestCulture = result; winningProvider = provider; break; } } } context.SetFeature<IRequestCultureFeature>(new RequestCultureFeature(requestCulture, winningProvider)); SetCurrentThreadCulture(requestCulture); await _next(context); } private static void SetCurrentThreadCulture(RequestCulture requestCulture) {#if DNX451 Thread.CurrentThread.CurrentCulture = requestCulture.Culture; Thread.CurrentThread.CurrentUICulture = requestCulture.UICulture;#else CultureInfo.CurrentCulture = requestCulture.Culture; CultureInfo.CurrentUICulture = requestCulture.UICulture;#endif } }
RequestLocalizationMiddleware
註冊前的參數RequestLocalizationOptions
在IApplicationBuilderExtensions中,我們對於中介軟體RequestLocalizationMiddleware註冊時,需要傳入RequestLocalizationOptions類型的執行個體,大多數時候傳入的都是預設的無參執行個體。
我們看RequestLocalizationOptions類只有4個屬性,代碼如下:
public class RequestLocalizationOptions { public RequestLocalizationOptions() { DefaultRequestCulture = new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture); RequestCultureProviders = new List<IRequestCultureProvider> { new QueryStringRequestCultureProvider { Options = this }, new CookieRequestCultureProvider { Options = this }, new AcceptLanguageHeaderRequestCultureProvider { Options = this } }; } public RequestCulture DefaultRequestCulture { get; set; } public IList<CultureInfo> SupportedCultures { get; set; } public IList<CultureInfo> SupportedUICultures { get; set; } public IList<IRequestCultureProvider> RequestCultureProviders { get; set; } }
View Code
我們看到在無參的建構函式中,系統初始化了DefaultRequestCulture和RequestCultureProviders。系統會遍曆RequestCultureProviders尋找適應的語言,當找不到合適的語言時,使用DefaultRequestCulture。
- RequestCultureProviders:預設初始化三種多語言提供源:queryString、cookie、acceptHeader。
- SupportedCultures:系統支援的語言
- SupportedUICultures:系統支援的UI語言
- DefaultRequestCulture:預設的語言源
[當我們需要自訂RequestCultureProvider時,我們有倆種方式,自訂類繼承類RequestCultureProvider(或者直接繼承介面IRequestCultureProvider),或者將CustomRequestCultureProvider註冊到RequestCultureProviders中,並在CustomRequestCultureProvider類建構函式中註冊Task<RequestCulture>方法]
註冊時的順序
系統是按照RequestLocalizationOptions中RequestCultureProviders的順序擷取合適的語言,如果沒有則使用DefaultRequestCulture。預設情況,系統會根據queryString、cookie、acceptHeader(預設最多取前三項語言)的順序讀取<是短路演算法>。
註冊後的RequestCultureFeature
Asp.net5 的運行時環境Context可以註冊不同類型的參數,所以系統最後註冊了IRequestCultureFeature介面的執行個體。
context.SetFeature<IRequestCultureFeature>(new RequestCultureFeature(requestCulture, winningProvider));
整體結構
整個工程的檔案可以用以下結構表示:
[Asp.net 5] Localization-Asp.net運行時多語言