繁体   English   中英

温莎城堡为给定的服务提供多种组件

[英]Windsor Castle multiple components for a given service

我有一个ILog接口和2个可能的实现:控制台日志和文件日志。 我在MVC应用程序中使用Windsor Castle,因此我在控制器安装程序中有以下代码:

container.Register(
            Component.For<ILogFactory>().ImplementedBy<LogFactory>().Named("first").OnCreate(x => x.initialize(LogType.Console, null)).LifestyleSingleton(),
            Component.For<ILogFactory>().ImplementedBy<LogFactory>().Named("second").OnCreate(x => x.initialize(LogType.File, null)).LifestyleSingleton(),
            Component.For<ILog>().UsingFactoryMethod(kernel => kernel.Resolve<ILogFactory>("first").GetLog(LogType.Console)).Named("first_log").LifestyleSingleton(),
            Component.For<ILog>().UsingFactoryMethod(kernel => kernel.Resolve<ILogFactory>("second").GetLog(LogType.File)).Named("second_log").LifestyleSingleton()
        );

在我的TestController中,我有以下代码:

private ILog log;

public TestController(ILog _log)
{
    log = _log;
}

我想知道如何决定注入名为first_log或second_log的ILog

回复晚了非常抱歉。

您可以使用子顺从解析程序。 它允许您为另一个组件的依赖关系解析特定组件。 下面的代码应该(未经测试)根据TestController构造函数中参数的名称解析ILog。 所以TestController(ILog优先)将解析名为first的ILog。

class SubDepResolver : ISubDependencyResolver
{
  private IKernel kernel;
  SubDepResolver(IKernel kernel)
  {
    this.kernel = kernel;
  }

  public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
    DependencyModel dependency)
  {
    if (model.GetComponentType() != typeof(TestController)) return false;
    if (dependency.GetComponentType() != typeof(ILog)) return false;
    return true;
  }

  public object Resolve(
    CreationContext context, 
    ISubDependencyResolver contextHandlerResolver, 
    ComponentModel model,
    DependencyModel dependency)
  {
    var handlers = kernel.GetHandlers(typeof(ILog));
    var handler = handlers.Single(h => h.GetComponentName() == dependency.DependencyKey);
    return handler.Resolve(context);
  }
}

使用以下方法添加解析器:

container.Kernel.Resolver.AddSubResolver(new SubDepResolver(container.Kernel));

祝你好运,Marwijn。

我为我的场景找到了解决方案。 TestController需要定义2个ILog:

public class TestController : Controller 
{ 
private ILog log1; 
private ILog log2; 

public TestController(ILog _log1, ILog _log2) 
{ 
log1 = _log1; 
log2 = _log2; 
identifier = _identifier; 
}

然后有必要添加:

container.Register(
Component.For<MyController>().DependsOn(
 ServiceOverride.ForKey("_log1").Eq("first_log"),
 ServiceOverride.ForKey("_log2").Eq("second_log")).LifestyleTransient()
 );

替换实际的默认内容:

container.Register(
 Classes.
 FromThisAssembly().
 BasedOn<IController>().
 If(c => c.Name.EndsWith("Controller")).
 LifestyleTransient());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM