1

我有一个项目,我使用 Castle Windsor 进行依赖注入,更具体地说,我使用的是 XML 配置,因此可以根据参数以不同的方式运行公共服务。

例如(真的很简化):

<component id="Processors" service="System.Collections.Generic.IEnumerable`1[[Services.Interfaces.IProcessor, Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" type="System.Collections.Generic.List`1[[Services.Interfaces.IProcessor, Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]">
  <parameters>
    <collection>
      <list>
        <item>${Processor1}</item>
        <item>${Processor2}</item>
      </list>
    </collection>
   <parameters>
</component>

<component id="Processor1" service="Services.Interfaces.IProcessor" type="Services.TestProcessor, Services">
  <parameters>
        <example>LIVE</example>
        <id>Processor1</id>
  </parameters>
</component>

<component id="Processor2" service="Services.Interfaces.IProcessor" type="Services.TestProcessor, Services">
  <parameters>
        <example>TEST</example>
        <id>Processor2</id>
  </parameters>
</component>

在运行时,我们解析名为 Processors 的组件,并依次遍历所有调用每个项目的项目。

正如您在上面的示例中看到的,我们在每个处理器上都有一个名为 id 的参数,这主要用于日志记录,并且对于跟踪哪个处理器有问题(并通过代理配置)非常有用。理想情况下,如果我可以重用组件配置中的 id(减少配置),那就太好了。

关于如何做到这一点的任何想法?

4

1 回答 1

1

对于使用“组件 id/name 作为参数”部分,您可以定义 custom Castle.MicroKernel.ISubDependencyResolver,例如:

public class InjectIdSubDependencyResolver : ISubDependencyResolver
{
    private const string SpecialName = "id";

    public bool CanResolve(
        CreationContext context, ISubDependencyResolver contextHandlerResolver, 
        ComponentModel model, DependencyModel dependency) 
        => 
        dependency.TargetType == typeof(string)
        &&
        dependency.DependencyKey == SpecialName
        &&
        dependency.Parameter?.ConfigValue == null;

    public object Resolve(
        CreationContext context, ISubDependencyResolver contextHandlerResolver, 
        ComponentModel model, DependencyModel dependency) 
        => model.Name;
}

你这样设置:

        IWindsorContainer wc = ...;
        wc.Kernel.Resolver.AddSubResolver(new InjectIdSubDependencyResolver());

然后 XML 配置得到简化......

<component id="Processor1" service="Services.Interfaces.IProcessor" type="Services.TestProcessor, Services">
  <parameters>
        <example>LIVE</example>
  </parameters>
</component>

<component id="Processor2" service="Services.Interfaces.IProcessor" type="Services.TestProcessor, Services">
  <parameters>
        <example>TEST</example>
  </parameters>
</component>

笔记

另外,我不会在容器中注册通用列表,而是使用第二类以及Collection Sub Dependency resolver,即

public class Processors {
    public Processors(IEnumerable<IProcessor> collection) { /**/ }
}

...甚至尝试使用类型化工厂

希望能帮助到你。

于 2017-11-20T23:08:13.083 回答