2016-12-19 14 views
1

私はWindsorコンテナがIoCのために使用される新しいプロジェクトを持っています。詳細にこれらの行を理解するためにWindsorコンテナ。 ASP.NET MVCアプリケーションのオブジェクトの寿命

ここでは単純化されたコードは、私は公式documenationで見つかった

public void Install(IWindsorContainer container, IConfigurationStore store) 
{ 
    container.Register(Classes.FromThisAssembly().BasedOn<BaseController>().LifestyleTransient(), 
         Component.For<ISecurityManager>().ImplementedBy<SecurityManager>(), 
         Component.For<IAccountManager>().ImplementedBy<AccountManager>() 
         ........) 
} 

情報をインストールして実行では十分ではありません。

Classes.FromThisAssembly().BasedOn<BaseController>().LifestyleTransient(), 

Registerメソッドでこの行はBaseControllerから継承されている自分のアプリケーション内のすべてのクラスに依存性の注入を可能にします。

BaseControllerが含まれています。

注射は、上記以外のクラスには行われません。

すべてのコントローラクラスの有効期間がインスタンスになることをコンテナに示します。

Component.For<ISecurityManager>().ImplementedBy<SecurityManager>() 

上記のすべてのコントローラに、コンストラクタインターフェイスがある場合、ISecurityManagerはSecurityManagerクラスのインスタンスに挿入されます。

このSecurityManagerのライフタイムは、デフォルト値としてシングルトンです。アプリケーションの起動後、アプリケーションの実行が終了するまで、すべてのコントローラに対して1つのSecurityManagerインスタンスしか持ちません。

私の考えは正しいですか?それは少なくとも、コントローラのLifestyleTransient()が私に奇妙に思えるし、注射されたオブジェクトもシングルトンになるからだ。下から上へ

答えて

4

:このセキュリティマネージャの

寿命は、デフォルト値としてシングルトンです。アプリケーションの起動後、アプリケーションの実行が終了するまで、すべてのコントローラに対して1つのSecurityManagerインスタンスしか持ちません。

これはまさにこれです。

少なくとも、コントローラのLifestyleTransient()が私を奇妙に思っていて、注入されたオブジェクトもシングルトンになるからです。

コントローラは、HttpContextを保持しているため一時的です。コントローラは、現在のユーザー要求と次の応答に関する情報を持っています。 HttpContextはリクエストごとであり、ブラウザ/クライアントが何か要求するたびに作成されます。

なぜコントローラが他のサービスよりも寿命が短いのか理解できます。これは、アプリケーションの内部アーキテクチャに大きく依存します。なぜ他の誰かがより良いアイデアを持っているなら、私は学びたいと思っている以上のものです。

あなたのコントローラの登録/解決/リリースサイクルは、カスタムコントローラファクトリを作成し、デフォルトを代入することによって行うことができます。

public class WindsorControllerFactory : DefaultControllerFactory 
{ 
    private readonly IKernel _kernel; 

    public WindsorControllerFactory(IKernel kernel) 
    { 
     _kernel = kernel; 
    } 

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
    { 
     if (controllerType == null) 
     { 
      throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path)); 
     } 

     if (_kernel.GetHandler(controllerType) != null) 
     { 
      return (IController)_kernel.Resolve(controllerType); 
     } 
     return base.GetControllerInstance(requestContext, controllerType); 
    } 

    public override void ReleaseController(IController controller) 
    { 
     _kernel.ReleaseComponent(controller); 
    } 
} 

とどこかに置く:

私のコントローラはあまりにも持って
container.Register(Component.For<IControllerFactory>().ImplementedBy<WindsorControllerFactory>()); 

シングルトン依存。このようにして、パイプラインプログラミングモデルを実現することができます。コントローラーからの要求を一連のオブジェクトに振り向け、結果を返すことができます。

SecurityManagerにAuthenticationまたはAuthorizationと関係がある場合は、IAuthorizationFilterまたはAuthorizeAttributeのようなMVCデフォルトのFilteringメカニズムを使用する方が良いかもしれません。もちろん、これはデータアクセスフィルターかもしれませんし、別のオブジェクトに配置するのが妥当かもしれません。

私はあなたの質問に答えましたか?