5

ローカライズされたデータを処理する必要があります。ローカライズされたすべての応答Dtoは、同じプロパティを共有します。ILocalizedDtoつまり、これらのDtoをマークするためのインターフェイス()を定義しました。リクエスト側には、ILocalizedRequestローカリゼーションを要求するリクエストがあります。

使用してIPlugin、私はすでに必要な機能を実装することができました。ただし、実装がスレッドセーフではないことは間違いありません。さらに、1つの要求/応答サイクルの識別子としてIHttpRequest.GetHashCode()を使用できるかどうかもわかりません。

リクエストとレスポンスの両方のDtoを利用するServiceStackプラグインを実装する正しい方法は何でしょうか?つまり、データを格納するための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();
    }
}
4

1 に答える 1

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-Language" と共に言語に挿入する機会を提供する です。?? DefaultLanguage(翻訳用のデフォルト言語を挿入するために別のことを行うこともできます...)

このように指定されていない場合はLanguage、リクエストのセットがリクエストの から読み取られてItems使用されます。

編集:さらに、@mythz で指摘されているようrequest.Dtoに、InterceptResponseメソッドでリクエスト DTO にアクセスすることもできます。

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);
    }
}
于 2015-08-23T20:59:43.080 に答える