2016-12-27 8 views
2

Simple Injectorを使用して.netコアWebApiサービスを作成しようとしています。私のStartup.csで私はこれを持っています:Simple Injectorを使用しているasp.net Core Web APIサービスの正しいDefaultScopedLifestyleは何ですか?

public Startup(IHostingEnvironment env) 
{ 
    // Setup configuration stuff 
    container = new Container(); 
    container.Options.DefaultScopedLifestyle = new AspNetRequestLifestyle(); // This is as specified in the docs. 
} 

public void ConfigureServices(IServiceCollection services) 
{ 
    // Add framework services. 
    services.AddMvc(); 
    services.AddOptions(); 
    services.AddSingleton<IControllerActivator>(
     new SimpleInjectorControllerActivator(this.container)); 
} 

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    app.UseSimpleInjectorAspNetRequestScoping(this.container); 

    InitializeContainer(app);  // This registers stuff 

    this.container.Verify();   // This blows up. 
    app.UseMvc(); 
} 

private void InitializeContainer(IApplicationBuilder app) 
{ 
    // Add application presentation components: 
    this.container.RegisterMvcControllers(app); 
    this.container.RegisterSingleton(new Log4NetAdapter(LogManager.GetLogger("Services.Api").Logger)); 

    // Register other stuff here. 
} 

これはうまくコンパイルされます。しかし、私はcontainer.Verify()ステップに次のエラーメッセージを取得するサービスを開始しようとすると:

{ "の設定は無効となり次の診断の警告が報告されました:。 は - [使い捨て過渡コンポーネント] MessageControllerは次のように登録されています過渡的には、しかし、IDisposableインターを実装 が警告に関する詳細な情報については、Errorプロパティを参照してください問題を解決する方法と、個別の警告を抑制する方法https://simpleinjector.org/diagnostics参照してください "}

- 。。。[使い捨て過渡コンポーネント] MessageControllerは一時的なものとして登録され、 IDisposableを実装しています。 設定が無効です。次の診断警告が報告されました。 警告の詳細については、Errorプロパティを参照してください。問題を解決する方法と個々の警告を抑制する方法については、https://simpleinjector.org/diagnosticsを参照してください。

私はWebApiRequestLifestyleを使用するために必要なnugetパッケージを含むしようとしたが、それ はそれが標準の.NETプロジェクトでのみ有効です表示されます。 .netコアではありません。

文書内にthis pageが見つかりました。私は、特定のコントローラの警告を無視してサービスを実行することができるよ:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    app.UseSimpleInjectorAspNetRequestScoping(this.container); 

    InitializeContainer(app);  // This registers stuff 

    var registration = container.GetRegistration(typeof(MessageController)).Registration; 

    registration.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent, "This is a Web API controller. Disposal should be handled by the system."); 

    this.container.Verify();   // Now this works 
    app.UseMvc(); 
} 

それに伴う問題は、今私が行くとすべての追加のコントローラの警告を抑制しなければならないということです。デフォルトのライフスタイルによって処理されるべきではありませんか?

+0

どのバージョンのSIと統合パッケージを使用していますか? – Steven

答えて

2

ASP.NETコアの場合、スコープ付きライフスタイルはAspNetRequestLifestyleです。コアMVCやCore Web APIアプリケーションを構築しているかどうかは関係ありませんが、このライフスタイルはすべての人に役立ちます。

あなたが得ているエラーは、選択したスコープ付きライフスタイルとは関係ありません。スコープ付きのライフスタイルを設定していない場合は、まったく同じライフスタイルになります。

あなたがthe integration guideに従っている場合、次のコード行表示されます:RegisterMvcControllersは(adviced practiceである)あなたのためのすべてのコントローラを登録し、そうしながら、コントローラごとにこの抑制を適用します

container.RegisterMvcControllers(app); 

をあなたのために。コントローラーに関するMVCにはdesign flawがあるので、警告を抑止することは不可欠です。コントローラの基底クラスはIDisposableを実装しており、これによってそれぞれの派生コントローラにも同様に実装されます。これはDependency Inversion Principle違反です。

コントローラではIDisposableが実装されているため、シンプルインジェクタではトランジェントが存在する可能性があるため、シンプルインジェクタはトランジェントを処理しないため、処分が必要なトランジェントコンポーネントが表示されるため警告します。後で処分するために保管される)。

典型的な解決策は、Scopedのような使い捨てコンポーネントを登録することですが、コントローラの場合は、すべての依存性が(少なくとも)スコープである必要があるため、これも複雑になります。

したがって、は、派生クラスがDispose(bool)をオーバーライドするかどうかを分析することです。 Dispose(bool)を上書きしない場合、警告は表示されません。 Disposeをオーバーライドしない場合は、基本クラスが何も処理しないため、警告を抑制することができます(そのため、基本クラスはIDisposableを実装していないはずです)。つまり、コントローラー内でDispose(bool)をオーバーライドすると、(正しい)この警告ポップアップが再度表示されます。

私の最高の推測では、どちらかMessageControllerオーバーライドDispose(bool)またはMessageControllerDispose(bool)をオーバーライドするカスタム基本クラスから派生していることです。お使いのコントローラがほとんどないロジックを配置している必要があり

注:

  • コントローラのみプレゼンテーションロジックを扱うべきである、これは他のロジックはあなたがコントローラに注入別のクラスに抽出されなければならないことを意味しています。
  • アプリケーションコンポーネント(コントローラなど)は、受信する依存関係を処理しないでください。これはあなたのDIコンテナがあなたのために処理すべきものです。

まれにコントローラが実際に処理を行う必要がある場合がありますが、その特定のコントローラのデフォルト登録を無効にしてスコープとして登録することができます。これにより、要求が終了したときにコントローラが廃棄されるようになります。

したがって、RegisterMvcControllersメソッドは、ASP.NET Core MVCのこのデザインの周りにこの醜いハックを実装しています。

+0

Hrm。私はInitializeContainer(app)メソッドでRegisterMvcControllersを呼び出しています。最初の質問からそれを離れることに対する私のせいです。私は可視性のためにそれを追加します。それは、あなたが説明したように行動しているようには見えません。 – Necoras

+0

@NecorasはあなたのMessageControllerを 'Dispose(bool)'に置き換えますか? – Steven

+0

いいえ、かなり単純なAPIコントローラです。それは、コンストラクタ、Get、Delete、Post、および追加の非標準GetCountのメソッドを持っています。 – Necoras

関連する問題