2011-09-21 55 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