我有一个项目,我使用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(减少配置),那将是很好的。
关于如何做到这一点的任何想法?
答案 0 :(得分:1)
使用&#34;组件ID /名称作为参数&#34;另外,您可以定义自定义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) { /**/ }
}
...甚至尝试使用Typed Factories
希望它有所帮助。