我有2个相同接口的实现,如果用户登录则要使用implementation1,如果用户没有登录则要使用implementation2。如何使用castle windsor进行配置?
答案 0 :(得分:8)
您可以添加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 :(得分: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");