8

現在、私はAsp.Net Web APIプロジェクトに依存関係を解決するためにSimple Injectorを使用しています。あなたがそのようにそれを設定することができますドキュメントからSimple InjectorとIHttpControllerActivatorを使用してASP.NET Web APIの依存関係を解決する

:ここ

protected void Application_Start() { 
    // Create the container as usual. 
    var container = new Container(); 
    container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(); 

    // Register your types, for instance using the scoped lifestyle: 
    container.Register<IUserRepository, SqlUserRepository>(Lifestyle.Scoped); 

    // This is an extension method from the integration package. 
    container.RegisterWebApiControllers(GlobalConfiguration.Configuration); 

    container.Verify(); 

    GlobalConfiguration.Configuration.DependencyResolver = 
     new SimpleInjectorWebApiDependencyResolver(container); 

    // Here your usual Web API configuration stuff. 
} 

主なポイントは、Web APIのコントローラを登録し、カスタム依存リゾルバを設定します。

しかし、私はちょうどAsp.NetのWeb APIの依存性注入を設定する方法のマーク・シーマンからこれらの記事を読んだ:これらの記事から

を、I IDependencyResolverを実装してWeb APIの依存関係を解決するよりも良い選択肢があることを知りました。 この他のオプションは、IoCコンテナを介してアダプタとして機能するIHttpControllerActivatorの実装を作成することです。ここで

私はSimpleInjectorを使用してコード化されてきた実装です。このラインで

GlobalConfiguration.Configuration.DependencyResolver = 
    new SimpleInjectorWebApiDependencyResolver(container); 

public class SimpleInjectorControllerActivator : IHttpControllerActivator 
{ 
    private readonly Container _container; 

    public SimpleInjectorControllerActivator(Container container) 
    { 
     _container = container; 
    } 

    public IHttpController Create(HttpRequestMessage request, 
     HttpControllerDescriptor controllerDescriptor, Type controllerType) 
    { 
     request.RegisterForDispose(_container.BeginExecutionContextScope()); 

     return (IHttpController)_container.GetInstance(controllerType); 
    } 
} 

Application_Start方法で、私はこの行を置き換えました

GlobalConfiguration.Configuration.Services.Replace(
    typeof(IHttpControllerActivator), 
    new SimpleInjectorControllerActivator(container)); 

IHttpControllerActivatorの実装がわかっていると思いますこのアプローチが有効で、正常なものと同じくらいうまくいくかどうかを確認します。

+1

更新されたバージョンをポストするのではなく、SimpleInjectorControllerActivatorの簡略版で質問を更新しました。 – Steven

答えて

3

はい、実装は有効です。

SimpleInjectorWebApiDependencyResolverSimpleInjectorControllerActivatorの両方を同じアプリケーションで使用しないように注意してください。両方ともExecutionContextScopeを開始し、同じWeb要求内に2つのスコープを持つことにつながる可能性があるため、相互に排他的です。

依存関係リゾルバに対してコントローラアクティベータを使用する一般的な利点は、依存関係リゾルバ契約によって、サービスを作成できないときにアダプタがnullを返すことが強制されることです。これは開発者が遭遇する非常に一般的な問題であり、多くの場合、混乱しているcontroller does not have a default constructor例外が発生します。この問題は、IHttpControllerActivatorを使用している場合は存在しません。これは、コントラクトによって値が返されるか、例外がスローされるためです。

しかしシンプルなインジェクターのWeb APIの統合プロジェクトは、決してnullを返さない(代わりに例外をスロー)の場合には要求されたサービスは、APIのコントローラである(そして、それによって暗黙的にIDependencyResolverの契約を破って、依存リゾルバでこの問題を回避します)。

SimpleInjectorDependencyResolverを使用する利点は、request.GetDependencyScope()メソッドを呼び出すことによってこのスコープの作成をトリガできるため、実行コンテキストスコープ内で動作するメッセージハンドラを作成する方が簡単になることです。現在の実装では、コントローラが作成される時点(ハンドラを実行した後)にスコープが開始されます。これを変更することはそれほど難しいことではありませんが、コントローラアクチベータを変更し、実行コンテキストスコープを開始する最も外側のハンドラを持っています(または実行コンテキストスコープを管理する依存リゾルバに再度落ちます)。

Mark Seemannの主張の1つは、components don't require this context during constructionである限り、非常に有効な点である文脈を渡すのが難しくなるということです。しかし、HttpRequestMessageにアクセスするのに役立つextension methodがあるので、これはあなたがSimple Injectorを使用するときに経験する問題ではありません。したがって、IDependencyResolverの抽象化はコンテキスト情報を取得するために設計されていませんが、このコンテキスト情報を取得する方法はあります。

これまではすべてのDIコンテナで一般的に行われていたため、IDependencyResolverのアダプタを使用することに決めました。私はこの決定を後悔しましたが、SimpleInjectorDependencyResolverを使用することは、通常、Simple InjectorをWeb APIにプラグインする最も簡単な方法です。 SimpleInjectorControllerActivatorも追加することを検討しましたが、これはほとんどのユーザーには実用的なメリットはありませんでしたが、何を使用するかについては文書化しなければなりませんでした。そこで、依存リゾルバアダプタを使用することにしました。アクティブ化のためのアダプタは、必要な人のために簡単に作成できます。

しかし、ASP.NETコアの場合は、別の方向に進みました。the documentationのように、実際には統合パッケージにはSimpleInjectorControllerActivatorが含まれています。 ASP.NETコアでは、コントローラアクティベータは完全なインターセプトポイントであり、OWINのようなパイプラインのために、スコープをリクエストに簡単にラップすることができます。したがって、ASP.NETコアでは、コントローラアクティベータをインターセプトポイントとして使用することをお勧めします。

+0

ありがとうSteven!私はこのアプローチがasp.netのコアコンテキストで有効であるのだろうかと疑問に思っているので、asp.netコアフレームワークを調べる必要があります。 – Thomas

+0

シンプルなインジェクタを使用して、デフォルトのWeb API統合としてこのアプローチを使用する可能性はありますか? – Thomas

+0

この特定のケースでは、 'SimpleInjectorControllerActivator'を' SimpleInjectorWebApiDependencyResolver'よりも 'ExecutionContext'を両方とも起動すると、その利点は何ですか? 'ControllerActivator'を使用して得ることのできる* Context *情報の種類は、' DependencyResolver'を使って取得できません。 –

関連する問題