2016-09-22 1 views
0

コントローラ正しく設定範囲WEBAPI、SimpleInjectorとMediatRを取得()アクションの最初の要求に

public class LocationsController : ApiController 
{ 
    private readonly IMediator _mediator; 

    public LocationsController(IMediator mediator) 
    { 
     _mediator = mediator; 
    } 

    public IEnumerable<Place> Get() 
    { 
     return _mediator.Send(new GetLatestMapData<Place>()); 
    } 
} 

を使用する場合、ハンドラはSimpleInjectorによってインスタンス化され、正しく実行されます。第2の要求(例えばためのブラウザでF5)で

、それはで失敗:

ハンドラタイプの要求のために見つかりませんでした....

容器またはサービスロケータ正しく構成かあなたのコンテナに登録されていないハンドラ

と内部例外:

が配置されたオブジェクトにアクセスすることはできません。

オブジェクト名: 'ThreadLocalオブジェクトが破棄されました。' WebAPIのプロジェクトのための

OWINスタートアップ

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     // SimpleInjector 
     var container = CompositionRoot.CreateContainer(); 

     var config = GlobalConfiguration.Configuration; 

     config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container); 

     // Routing 
     config.MapHttpAttributeRoutes(); 

     config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", 
      new { id = RouteParameter.Optional }); 

     config.EnsureInitialized(); 

     app.UseWebApi(config); 
    } 
} 

SimpleInjector IPackageは

public class Installer : IPackage 
{ 
    public void RegisterServices(Container c) 
    { 
     c.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(); 

     c.RegisterWebApiControllers(GlobalConfiguration.Configuration); 
    } 
} 

私はハンドラが正しく作成されている何が起こっているかと思いますし、最初の要求の後に配置されました。 ここで、理由はわかりませんが、その後のリクエストでは、ハンドラは再作成されません。

c.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(false 
/*disposeInstanceWhenScopeEnds*/); 

質問を

  1. 私はfalseに設定disposeInstanceWhenScopeEndsパラメータを維持する必要があります:私は「スコープが終了したときに処分しない」にWebApiRequestLifestyleを変更した場合、それはすべての要求のために働くので、私はこれを知っていますか?
  2. そうでない場合、正しい解決策は何ですか?
  3. これはsolved before by creating a LifetimeScopeDecoratorでしたが、確かにこの機能は既にSimpleInjector WebApi統合ライブラリによって提供されていますか?私は何が欠けていますか?

(そして、お読みいただきありがとうございました)

+0

container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(); container.Options.LifestyleSelectionBehavior = new WebApiInjectionLifestyle(); internal class WebApiInjectionLifestyle : ILifestyleSelectionBehavior { public Lifestyle SelectLifestyle(Type serviceType, Type implementationType) { return Lifestyle.Scoped; } } 

詳細

を適切なスタックトレースを追加してください、 – Steven

答えて

0

このlinkは、依存関係の解決に優れたガイダンスを提供し、IDependencyResolver/IDependencyScopeインタフェースを使用します。

直ちに、彼らは少しトリッキーな傾向がある寿命に触れることがわかります。

特にこのセクションでは、興味深いものです:

Dependenecyスコープとコントローラの寿命

コントローラは、リクエストごとに作成されます。オブジェクトのライフタイムを管理するには、 IDependencyResolverはスコープの概念を使用します。

HttpConfigurationオブジェクトにアタッチされた依存関係リゾルバのグローバルスコープは です。 Web APIがコントローラを作成すると、BeginScopeが呼び出されます。 このメソッドは、子スコープを表すIDependencyScopeを返します。

Web APIは、子スコープでGetServiceを呼び出して コントローラを作成します。要求が完了すると、Web APIは 子スコープでDisposeを呼び出します。コントローラの の依存関係を破棄するには、Disposeメソッドを使用します。

通常、サービスの起動は、アプリケーションの起動時に1回発生し、その時点での依存関係を解決します。ワーカープロセスがシャットダウンしている(アクティビティがないなど)場合にのみ、disposeが呼び出されます。

通常、解決されたインスタンスは、使用後に破壊されることが不可欠でない限り、ライフサイクルに残っているのが普通です。しかし、与えられた例では、要求が完了したら正しく処理しなければならないと説明しています。したがって、ガイダンスとして提供された例を使用してインスタンスを正しく処分することをお勧めします。

これはIoCとWebApiで作業するときに役立ちました。私はこれが助けて欲しい!あなたの生涯を配置する必要がある

関連する問題