We're in process of migrating one stable project from Castle Windsor 2.5.2 to 3.0.
We use mixed xml/api registration. After switching to 3.0, parameters injected through ctor and defined in xml can't be resolved anymore.
To illustrate:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
...
<properties>
<frontEnd.url>http://site.com</frontEnd.url>
<admin.email>[email protected]</admin.email>
</properties>
<components>
...
<component id="ServicesBootstrapperAction"
service="SomeNS.Startup.IBootstrapperAction"
type="SomeNS.Service.ServicesBootstrapperAction, Project-Service"
>
<parameters>
<frontEndUrl>#{frontEnd.url}</frontEndUrl>
<adminEmail>#{admin.email}</adminEmail>
<prohibitedLogins>Assets/prohibited-logins.txt</prohibitedLogins>
</parameters>
</component>
...
</components>
</configuration>
And the registration:
_container.Install(
Castle.Windsor.Installer.Configuration.FromXmlFile("project.common.config"),
Castle.Windsor.Installer.Configuration.FromXmlFile(String.Format("project.{0}.config", RuntimeEnvironment))
);
After trying to resolve this component we get:
'SomeNS.Service.ServicesBootstrapperAction' is waiting for the following dependencies:
- Parameter 'frontEndUrl' which was not provided. Did you forget to set the dependency?
- Parameter 'adminEmail' which was not provided. Did you forget to set the dependency?
- Parameter 'prohibitedLogins' which was not provided. Did you forget to set the dependency?
Again, this is something that worked perfectly with 2.5 so I guess it might be some undocumented (or missed/not understood by us) breaking change.
Differential diagnosis, anyone?
UPDATE: I figured out the problem and have found a workaround. I don't like it but it works.
For all curious, here's the link to the project illustrating the problem: https://docs.google.com/open?id=0B7XFrOzGfmirSldZUmRQeU9SZDZZVnV5UGhGaGhsUQ
Feel free to tell me that I'm wrong and that I should have used some other beautiful solution (what?).
I think it's fair to close this issue since I've found a workaround for my original problem.
My true problem was that I had several implementations for one interface (and needed them all). But, some of the implementations required parameters (simple values) which naturally was moved to xml configuration file and other implementations were registered using conventions in code.
Now, to avoid double registrations I've used .Unless(container.Kernel.HasComponent) prior to 3.0, which is now supposedly obsolete, but compiled just fine!
Surprisingly, .Unless(t => container.Kernel.HasComponent(t.Name)) worked great as before!
I'm sure there's an explanation for this but I can't think of any.
I really love Castle and enjoy using it. But 45 kb of breaking changes is not cool, sorry guys.