views:

30

answers:

1

Inside a DLL, we've defined two classes ("Class1" and "Class2") which inherit from an interface ("IInterface") and a base class ("BaseClass").

We're using the Castle Windsor's Fluent Registration API ( http://using.castleproject.org/display/IoC/Fluent+Registration+API ) to automatically register all the classes inheriting from "BaseClass" (inside that DLL) to their respective interfaces.

For specific personalization, we've used (since today) a "castle.xml" file, which overrides (with "component" tags) the associations between interfaces and concrete classes (registered by the Fluent Registration Api). We load that xml file inside the WindsorContainer's constructor.

The code is something like this:

        //container's initialization:
        var resource = new FileResource("Castle.xml");
        var interpreter = new XmlInterpreter(resource);
        var container = new WindsorContainer(interpreter);
        container.AddFacility<TypedFactoryFacility>();

        //...

        //automatic type registration:
        container.Register(
            AllTypes
                .FromAssemblyContaining<BaseClass>()
                .BasedOn<BaseClass>()
                .WithService.Select(
                    (t1, t2) => t1.GetInterfaces()
                                    .Except(new[] {typeof (IDisposable)})
                                    .Union(new[] {t1}))
                .Configure(a => a.Named(a.ServiceType.Name)
                                    .LifeStyle.Transient)
                .AllowMultipleMatches()
            );

By default, if we ask Castle for IInterface object, we get "Class1"; to obtain "Class2", we have to specify it inside the "Castle.xml" file.

Today, I've tried to get rid of the castle.xml, specifying the "Component" directives inside the fluent configuration (BEFORE the "AllTypes" directive):

        container.Register(
            Component
                .For<IInterface>()
                .ImplementedBy<Class2>()
                .LifeStyle.Transient);

... but we still get a Class1 object, as if the "AllTypes" fluent directive overrode the "Component" one (and it's strange, 'cos the "component" directive inside the xml file works).

What am I doing wrong?

EDIT: I was accessing to the component by key name, ".Named()" solved the problem (thanks to Krzysztof):

        container.Register(
            Component
                .For<IInterface>()
                .ImplementedBy<Class2>()
                .Named(typeof(IInterface).Name)
                .LifeStyle.Transient);
+1  A: 

Just so that the question does not appear as unanswered, the answer is in the comments above.

Krzysztof Koźmic