Castle Windsor - 控制瞬态组件的创建

时间:2017-10-04 12:51:19

标签: c# .net dependency-injection castle-windsor

我是Castle Windsor的新手,请原谅我,如果我在这里错过了一个明显的功能......

我目前正在尝试将工作项目从纯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(&#34; LoggerName&#34;)),但LoggerImpl实例不会在容器中注册,我不知道是否那好不好。

任何评论,想法和建议都将不胜感激。

1 个答案:

答案 0 :(得分:2)

您可以使用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())