2011-09-21 20 views
7

同じインターフェースの2つの実装があり、ユーザーがログインしている場合はimplementation1を、ユーザーがログインしていない場合はimplementation2を使用したいと思います。Castle windor条件付き依存関係の追加

答えて

1

これを解決する方法の1つは、サービスをキーに登録し、必要に応じて解決することです。

public interface ISample 
{ 
    int Calculate(int a, int b); 
} 

class SampleB : ISample 
{ 
    public int Calculate(int a, int b) 
    { 
     return a + b + 10; 
    } 
} 

class SampleA : ISample 
{ 
    public int Calculate(int a, int b) 
    { 
     return a + b; 
    } 
} 

登録:

 container.Register(Component.For<ISample>().ImplementedBy<SampleA>().Named("SampleA").LifeStyle.Transient); 
     container.Register(Component.For<ISample>().ImplementedBy<SampleB>().Named("SampleB").LifeStyle.Transient); 

// SampleAが必要なときに解決します。

var sampleA = container.Resolve<ISample>("SampleA"); 

// SampleBが必要なときに解決します。

var sampleB = container.Resolve<ISample>("SampleB"); 
+1

ここで 'container.Resolve()'を呼び出しますか? –

+0

内部実装を変更/拡張しない限り、ユーザーがログインしているかどうかを知る方法はありません。その間に 'ログイン・イン・ファクタ'を考慮して希望の実装を与えるDeciderクラスがあります。 –

+0

Windsor *はこのためのメカニズムを持っています(mookidの答えを参照)、内部実装をまったく変更する必要はありません。 –

7

あなたが利用可能な実装は、例えば依存の間で選択することができるであろうhandler selector、追加することができますThread.CurrentPrincipalが設定されているかどうか(正しく覚えていれば、ASP.NET/MVCではHttpContext.Current.Request.IsAuthenticated)。

ハンドラセレクタは、おそらく多少次のようになります。ハンドラセレクタの

public class MyAuthHandlerSelector : IHandlerSelector 
{ 
    public bool HasOpinionAbout(string key, Type service) 
    { 
     return service == typeof(ITheServiceICareAbout); 
    } 

    public IHandler SelectHandler(string key, Type service, IHandler[] handlers) 
    { 
     return IsAuthenticated 
      ? FindHandlerForAuthenticatedUser(handlers) 
      : FindGuestHandler(handlers); 
    } 

    bool IsAuthenticated 
    { 
     get { return Thread.CurrentPrincipal != null; } 
    } 
    // .... 
} 

唯一の欠点は、それらがコンテナから引かれていないということです - 彼らは、登録時にコンテナへのインスタンスとして追加されます。すなわち彼らは従属性の注入や生活習慣の管理などをすることはありませんが、それを緩和する方法があります。その方法を知りたい場合はF.T.Windsorをご覧ください。

+1

3.0バージョンのものが変わったのかと疑問に思っています。 – Giedrius

関連する問題