我是温莎城堡的新手,如果我在这里错过了明显的功能,请原谅我...
我目前正在尝试将一个工作项目从纯DI切换到Castle。我有几个组件,它们具有ILogger类型的属性依赖关系。我的LoggerImpl是通过静态工厂方法创建的,如下所示:
LoggerImpl.GetLogger("LoggerName");
当前具有ILogger依赖项的每个组件(纯DI)在构造对象树时都会收到一个命名记录器,例如:
var component1 = new MyComponent1(dependencies...);
component.Logger = LoggerImpl.GetLogger("Component1Logger");
var component2 = new MyComponent2(dependencies...);
component.Logger = LoggerImpl.GetLogger("Component2Logger");
切换到Castle Windsor之后,我为引用它的每个组件注册了一个名为ILogger的单例,然后使用DependsOn(...)将这些记录器分配给我的组件。该代码或多或少是这样的:
// register logger implementations
container.Register(Component.For<ILogger>()
.ImplementedBy<RolexLogger>()
.Named("Component1Logger")
.UsingFactoryMethod(() => LoggerImpl.GetLogger("Component1Logger"));
container.Register(Component.For<ILogger>()
.ImplementedBy<RolexLogger>()
.Named("Component2Logger")
.UsingFactoryMethod(() => LoggerImpl.GetLogger("Component2Logger"));
// register component implementations
container.Register(Component.For<IComponent1>()
.ImplementedBy<MyComponent1>()
.DependsOn(Dependency.OnComponent(typeof(ILogger), "Component1Logger")));
container.Register(Component.For<IComponent2>()
.ImplementedBy<MyComponent2>()
.DependsOn(Dependency.OnComponent(typeof(ILogger), "Component2Logger")));
这一切似乎都可行,但是我想知道是否有更简单的方法来做到这一点?这似乎是很多代码,随着越来越多的组件需要其记录器,代码将不断增长。
我想知道LoggerImpl是否可以通过Transient生活方式注册单个ILogger的实现,然后以某种方式控制每次解决ILogger的依赖关系时如何创建LoggerImpl实例?
我假设我在注册组件时也可以使用Dependency.OnValue(LoggerImpl.GetLogger(“ LoggerName”)),但是LoggerImpl实例不会在容器中注册,因此我不知道这样是否可以。
任何意见,想法和建议将不胜感激。
最佳答案
您可以使用subresolver
public class LoggerResolver : ISubDependencyResolver
{
public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
return dependency.TargetType == typeof(ILogger);
}
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
return LoggerImpl.GetLogger(model.Implementation.FullName);
}
}
而不是在您进行任何注册之前将其添加到内核中
container.Kernel.Resolver.AddSubResolver(new LoggerResolver())