Castle Windsor - управление созданием переходных компонентов

Я новичок в Castle Windsor, поэтому простите меня, если я просто пропустил очевидную функциональность здесь...

В настоящее время я пытаюсь переключить рабочий проект с чистого DI на замок. У меня есть несколько компонентов, которые имеют свойство зависимости типа 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")));
</mycomponent2></icomponent2></mycomponent1></icomponent1></rolexlogger></ilogger></rolexlogger></ilogger>

Это все работает, но мне было интересно, есть ли более простой способ сделать это? Это похоже на очень много кода, который будет расти и расти, поскольку все больше компонентов нуждаются в их регистраторах.

Мне было интересно, можно ли зарегистрировать единую реализацию ILogger с помощью LoggerImpl с образом жизни Transient, а затем каким-то образом контролировать, как экземпляры LoggerImpl создаются каждый раз, когда зависимость от ILogger разрешается?

Я предполагаю, что я мог бы также использовать Dependency.OnValue(LoggerImpl.GetLogger("LoggerName")) при регистрации компонентов, но тогда экземпляры LoggerImpl не будут зарегистрированы в контейнере, и я не знаю, ОК это или нет.

Будем очень благодарны за любые комментарии, идеи и предложения.

1 ответ

Вы можете использовать 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())

licensed under cc by-sa 3.0 with attribution.