2011-09-21 56 views
7

我有2個實現相同的接口,並希望使用implementation1如果用戶登錄或implementation2如果用戶沒有登錄。我怎樣才能配置這與城堡windsor?城堡windor添加條件依賴

回答

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

Windsor無法知道用戶是否登錄,除非您更改/擴展它的內部實現。可以有一個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