7

現在、AutoMapper が私たちのプロジェクトに役立つかどうかを評価しています。私は ASP.NET Web API を使用して RESTful Web API に取り組んでおり、返さなければならないものの 1 つは、リンクを含むリソースです。次のドメイン オブジェクトを使用して、この単純化された例を検討してください。

public class Customer
{
    public string Name { get; set; }
}

これをリソース オブジェクトにマップする必要があります。これは DTO のようなものですが、REST を容易にするためのプロパティが追加されています。これは私のリソースオブジェクトがどのように見えるかです:

public class CustomerResource
{
    public string Name { get; set; }
    public Dictionary<string, string> Links { get; set; }
}

Links プロパティには、関連するリソースへのリンクを含める必要があります。現在、次のアプローチを使用してそれらを構築できます。

public IEnumerable<CustomerResource> Get()
{
    Func<Customer, CustomerResource> map = customer => 
        new CustomerResource
        {
            Name = customer.Name,
            Links = new Dictionary<string, string>()
            {
                {"self", Url.Link("DefaultApi", new { controller = "Customers", name = customer.Name })}
            }
        }

    var customers = Repository.GetAll();
    return customers.Select(map);
}

...しかし、これはかなり面倒で、ネストされたリソースなどがたくさんあります。私が見ている問題は、AutoMapper を使用できないということです。これは、マッピング操作が実行されるポイントにスコープされる、プロジェクション中に必要な特定のものを提供できないためです。この場合、ApiController の Url プロパティは、リンクを作成するために必要な UrlHelper インスタンスを提供しますが、それ以外の場合もあります。

この難問をどのように解決しますか?

PS私はこの質問のためにこのコードを入力しました。あなたの頭の中でコンパイルされましたが、あなたのお気に入りのIDEでは失敗するかもしれません.

4

2 に答える 2

2

Custom Type Converterの使用を検討します。型コンバーターは、IOC コンテナーを介して注入されたコンテキスト情報を持つことができます。または、コンバーターは構成時にインスタンス化されるため、型コンバーターが実行されるたびにコンテキスト情報を返すファクトリへの参照を持つことができます。

簡単な例

現在の「コンテキスト」を取得するためのインターフェイスを定義できます (それが何を意味するかは、実行していることと実装方法によって異なります。この例では、セッション、サーバー、アイテム、等...):

public interface IContextFactory
{
    HttpContext GetContext();
}

そして実装は簡単です:

public class WebContextFactory : IContextFactory
{
    public HttpContext GetContext()
    {
        return HttpContext.Current;
    }
}

カスタム型コンバーターは IOC コンテナーから IContextFactory のインスタンスを取得でき、マッピングが実行されるたびに GetContext() を呼び出して現在の要求のコンテキストを取得できます。

Url プロパティへのアクセス

UrlHelper は、現在のコントローラーのコンテキストにアタッチされた Request オブジェクトから取得されます。残念ながら、それは HttpContext では利用できません。ただし、ApiController の Initialize メソッドをオーバーライドし、controllerContext を HttpContext.Items コレクションに格納できます。

protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext)
{
    HttpContext.Current.Items["controllerContext"] = controllerContext;
    base.Initialize(controllerContext);
}

その後、現在の HttpContext からアクセスできます。

var helper = ((HttpControllerContext) HttpContext.Current.Items["controllerContext"]).Request.GetUrlHelper();

これが最善の解決策かどうかはわかりませんが、カスタム型マッパー内で UrlHelper インスタンスを取得できます。

于 2013-04-06T12:42:08.253 に答える