Castle Windsor 添加条件依赖项

8

我有两个相同接口的实现,希望在用户登录时使用implementation1,在未登录时使用implementation2。如何使用Castle Windsor配置这个呢?

2个回答

8
你可以添加一个处理程序选择器,它能够根据例如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
“handler selector”链接已经过时。实际链接为:https://github.com/castleproject/Windsor/blob/master/docs/handler-selectors.md - cly

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");

除非您更改/扩展其内部实现,否则Windsor不会知道用户是否已登录。可以在中间添加一个Decider类,该类将考虑“登录因素”并提供所需的实现。 - Shuhel Ahmed
Windsor确实有机制来实现这一点(请参见mookid的答案),不必更改其内部实现。 - Mauricio Scheffer
谢谢,我的意思是扩展而不是“修改”。对于mookids的回答加1。 - Shuhel Ahmed
1
只要静态服务定位器不是好主意,你只能在有容器访问权限的情况下使用此解决方案 - 而通常你没有。 - Giedrius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接