Frage

I'm having problems injecting an array of services via Castle Windsor with xml configuration. I've followed this link which explains it quite well, but somehow it doesn't work for me. Here's the code I'm using:

class Program
{
    static void Main(string[] args)
    {
        IWindsorContainer container = new WindsorContainer();
        container.Install(Castle.Windsor.Installer.Configuration.FromAppConfig());

        var consumer = container.Resolve<Consumer>();
    }
}

public class Consumer
{
    public Consumer(IFoo[] foos)
    {
        foreach (IFoo foo in foos)
            foo.Foo();
    }
}

public interface IFoo
{
    void Foo();
}

public class Foo1 : IFoo
{
    public void Foo() { }
}

public class Foo2 : IFoo
{
    public void Foo() { }
}

And here's the app.config:

<castle>
  <components>
     <component id="Foo1" service="Test.IFoo, Test" type="Test.Foo1, Test" />
     <component id="Foo2" service="Test.IFoo, Test" type="Test.Foo2, Test" />

     <component id="Consumer" service="Test.Consumer, Test">
        <parameters>
           <foos>
              <array>
                 <item>${Foo1}</item>
                 <item>${Foo2}</item>
              </array>
           </foos>
        </parameters>
     </component>
  </components>
</castle>

Strangely, the error I'm getting is the following:

Can't create component 'Test.Consumer' as it has dependencies to be satisfied.
'Test.Consumer' is waiting for the following dependencies:
- Service 'Test.IFoo[]' which was not registered.

Why does it expect IFoo[] as a service? Does that make any sense? Or maybe the link I'm referring to doesn't work any longer with the current version of Windsor (I'm on 3.1.0)?

War es hilfreich?

Lösung

To once again answer my own question (sorry ;-):

Turned out that the solution is quite simple - once you know. Adding an ArrayResolver as a subresolver not only makes this working:

    static void Main(string[] args)
    {
        IWindsorContainer container = new WindsorContainer();
        container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel));
        container.Install(Castle.Windsor.Installer.Configuration.FromAppConfig());

        var consumer = container.Resolve<Consumer>();
    }

But even simplyfies configuration, as you don't have to setup the instances:

  <configuration>
     <configSections>
        <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
     </configSections>
     <castle>
        <components>
           <component id="Foo1" service="Test.IFoo, Test" type="Test.Foo1, Test" />
           <component id="Foo2" service="Test.IFoo, Test" type="Test.Foo2, Test" />
           <component id="Consumer" service="Test.Consumer, Test"/>
        </components>
     </castle>
  </configuration>

As always it turns out that Castle Windsor is great, but documentation is not and the many different versions you'll find examples for in the web won't make it easier...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top