2013-03-11 21 views
5

我需要爲本地化數據提供服務。本地化的所有響應Dtos都共享相同的屬性。即我定義了一個接口(ILocalizedDto)來標記這些Dtos。在請求方面,需要本地化的請求有ILocalizedRequest如何編寫需要請求和響應的ServiceStack插件Dtos

使用IPlugin我已經設法實現了所需的功能。但是我確定實現不是線程安全的,另外我不知道我是否可以使用IHttpRequest.GetHashCode()作爲一個請求/響應循環的標識符。

實現一個ServiceStack插件的正確方法是什麼?它使用請求和響應Dto?即是否有一些IHttpRequest.Context存儲數據或可以在響應時間獲取請求dto?

internal class LocalizationFeature : IPlugin 
{ 
    public static bool Enabled { private set; get; } 

    /// <summary> 
    ///  Activate the localization mechanism, so every response Dto which is a <see cref="ILocalizedDto" /> 
    ///  will be translated. 
    /// </summary> 
    /// <param name="appHost">The app host</param> 
    public void Register(IAppHost appHost) 
    { 
     if (Enabled) 
     { 
      return; 
     } 
     Enabled = true; 
     var filter = new LocalizationFilter(); 
     appHost.RequestFilters.Add(filter.RequestFilter); 
     appHost.ResponseFilters.Add(filter.ResponseFilter); 
    } 
} 

// My request/response filter 
public class LocalizationFilter 
{ 
    private readonly Dictionary<int,ILocalizedRequest> localizedRequests = new Dictionary<int, ILocalizedRequest>(); 

    public ILocalizer Localizer { get; set; } 

    public void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto) 
    { 
     var localizedRequest = requestDto as ILocalizedRequest; 
     if (localizedRequest != null) 
     { 
      localizedRequests.Add(GetRequestId(req), localizedRequest); 
     } 
    } 

    public void ResponseFilter(IHttpRequest req, IHttpResponse res, object response) 
    { 
     var requestId = GetRequestId(req); 
     if (!(response is ILocalizedDto) || !localizedRequests.ContainsKey(requestId)) 
     { 
      return; 
     } 

     var localizedDto = response as ILocalizedDto; 
     var localizedRequest = localizedRequests[requestId]; 
     localizedRequests.Remove(requestId); 

     Localizer.Translate(localizedDto, localizedRequest.Language); 
    } 

    private static int GetRequestId(IHttpRequest req) 
    { 
     return req.GetHashCode(); 
    } 
} 
+0

看來你對IHttpRequest /響應的問題將被執行特定的。假設實現是ASP.NET,通常可以將東西存儲在HttpContext.Items集合中。不幸的是,IHttpContext似乎沒有公開它...... http://msdn.microsoft.com/en-us/library/ms689291%28v=vs.90%29.aspx – 2013-05-21 22:24:57

回答

2

第一關:爲什麼你需要請求本身,當所有你需要的是Language屬性的值?

下面的代碼是爲您的方案一個合法的解決方案:

public class LocalizationFeature : IPlugin 
{ 
    public const string LanguageKey = "X-Language"; 

    public void Register(IAppHost appHost) 
    { 
    this.GlobalRequestFilters.Add(this.InterceptRequest); 
    this.GlobalResponseFilters.Add(this.InterceptResponse); 
    } 

    private void InterceptRequest(IRequest request, 
           IResponse response, 
           object dto) 
    { 
    var localizedRequest = dto as ILocalizedRequest; 
    if (localizedRequest != null) 
    { 
     request.SetItem(LanguageKey, 
         localizedRequest.Language); 
    } 
    } 

    private void InterceptResponse(IRequest request, 
           IResponse response, 
           object dto) 
    { 
    var localizedDto = dto as ILocalizedDto; 
    if (localizedDto != null) 
    { 
     var language = request.GetParam(LanguageKey) ?? request.GetItem(LanguageKey); 
     if (!string.IsNullOrEmpty(language)) 
     { 
     Localizer.Translate(localizedDto, 
          language); 
     } 
    } 
    } 
} 

有趣的事情在這裏是var language = request.GetParam(LanguageKey) ?? request.GetItem(LanguageKey);,這讓你有機會與任何HTTP標頭,Cookie或表單數據注入語言(如果適用)和「X語言」鍵。 (您也可以做另一個?? DefaultLanguage以注入默認語言以進行翻譯...)

如果未以此方式提供,請求的集合Language將從請求的Items中讀取並使用。

編輯: 此外,作爲pointed out by @mythz,你也可以用request.Dto訪問請求DTO在InterceptResponse方法:

private void InterceptResponse(IRequest request, 
           IResponse response, 
           object dto) 
{ 
    var localizedRequest = request.Dto as ILocalizedRequest; 
    var localizedDto = dto as ILocalizedDto; 
    if (localizedRequest != null 
     && localizedDto != null) 
    { 
     Localizer.Translate(localizedDto, 
          localizedRequest.Language); 
    } 
} 
+0

此外請求DTO保存在'IRequest .Dto'和響應對象在'IResponse.Dto' – mythz 2015-08-23 22:27:57

+1

@mythz好趕上! – 2015-08-23 22:40:07