C #, Windsor Castle and composite design template

I developed a telemetry recorder for several separate platforms using a composite template

public interface ILogger { void Log(); } public class A : ILogger { public void Log(...); } public class B : ILogger { public void Log(...); } public class Many : ILogger { private readonly List<ILogger> m_loggers; public Many(IEnumerable<ILogger> loggers) { m_loggers = loggers.ToList(); } public void Log() { m_loggers.ForEach(c => c.Log()); } } 

Now I want to get the β€œMany” instance from the Windsor container, but have encountered several problems:

  • if all ILoggers are in the container, how can I be sure that I get a "lot" implementation, not "A" or "B"?

  • I tried to follow this example . Windsor Castle: How do I implement all interface implementations in ctor? and use container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel)); to register a class with an IEnumerable dependency, but if this class also implements IComponent without creating a circular dependency?

Am I trying to make something even possible?

+5
source share
2 answers

First of all, it is a composite design template, not a component.

The way you do this in Castle Windsor in your case should look like this:

 container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel)); container.Register(Component.For<ILogger>().ImplementedBy<Many>()); container.Register(Component.For<ILogger>().ImplementedBy<A>()); container.Register(Component.For<ILogger>().ImplementedBy<B>()); 

This works because Castle Windsor has an internal understanding of models such as Composite or Decorator, so no circular dependency will be created in this case. Just keep in mind that the registration procedure is important in this case.

Learn more about registering various templates with Castle Windsor here .

+4
source

Is it possible to use the factory method in registering a container?

  var container = new Castle.Windsor.WindsorContainer(); container.Register(Component.For<A>()); container.Register(Component.For<B>()); container.Register(Component.For<ILogger>() .UsingFactoryMethod(k => new Many(k.Resolve<A>(), k.Resolve<B>()))); var logger = container.Resolve<ILogger>(); 

After the change:

  public Many(params ILogger [] loggers) { m_loggers = loggers.ToList(); } 

Limited knowledge of the Windsor container will lead me to this, perhaps it has improved in the same direction, using factory to initialize your object. The important thing is that the configuration is inside the container (even if it is a little detailed)

0
source

Source: https://habr.com/ru/post/1233575/


All Articles