views:

728

answers:

2

Hi i am trying to inject a dictionary of interfaces but am getting an error from castle like this :-

Castle.MicroKernel.SubSystems.Conversion.ConverterException: No converter registered to handle the type IFoo

In order to go around the exception, I had to create a wrapper that contained a list of the Ifoo interface and returns it using a property. The wrapper was then used in the configuration ==> dictionary instead of dictionary

Is there a way in castle that I can just have a dictionary of Interface instead of doing this workaround ?

public interface IFoo {}
public class Foo {}
public class IfooWrapper {
    IList<IFoo> container{get;set;}
}
A: 

I've had to do something very similar. However I think it exposed a design flaw more than anything else. I refactored my app so that it did what your wrapper class does as its standard way of working. It drastically simplified the app as well.

It was really just a matter of doing things the "Castle Windsor way" instead of trying to adapt "my way" to the Castle Windsor model. It was pretty humbling to see how much easier and better the Castle Windsor way was...

Technically not a solution to the problem you posed but hopefully it helps you out.

Austin Salonen
hmm well not a solution, but thats what I figured. But what makes no sense to me is that a list of interfaces is allowed while a dictionary of interfaces is not. The wrapper class just adds more noise to the configuration.
+3  A: 

This works just fine for me (Windsor 2.0):

namespace WindsorTests {
    public interface IService {}    
    public class Service1 : IService {}    
    public class Service2 : IService {}    
    public class Consumer {
        private readonly IDictionary<string, IService> services;    
        public IDictionary<string, IService> Services {
            get { return services; }
        }    
        public Consumer(IDictionary<string, IService> services) {
            this.services = services;
        }
    }    

    [TestFixture]
    public class WindsorTests {    
        [Test]
        public void DictTest() {
            var container = new WindsorContainer(new XmlInterpreter(new StaticContentResource(@"<castle>
<components>
    <component id=""service1"" service=""WindsorTests.IService, MyAssembly"" type=""WindsorTests.Service1, MyAssembly""/>
    <component id=""service2"" service=""WindsorTests.IService, MyAssembly"" type=""WindsorTests.Service2, MyAssembly""/>
    <component id=""consumer"" type=""WindsorTests.Consumer, MyAssembly"">
        <parameters>
            <services>
                <dictionary>
                    <entry key=""one"">${service1}</entry>
                    <entry key=""two"">${service2}</entry>
                </dictionary>
            </services>
        </parameters>
    </component>
</components>
</castle>")));
            var consumer = container.Resolve<Consumer>();
            Assert.AreEqual(2, consumer.Services.Count);
            Assert.IsInstanceOfType(typeof(Service1), consumer.Services["one"]);
            Assert.IsInstanceOfType(typeof(Service2), consumer.Services["two"]);
        }
    }
}
Mauricio Scheffer
aha, they could have fixed this in windsor 2.0 . I am using 1.0 rc 3
Sorry, I don't think this works in RC3
Mauricio Scheffer