I’m using Castle.Windsor in my application. My components and their parameters are configured within the app.config file. But I also want to be able to pass parameters by command line arguments. That means cmd-args > config-args. I tried to use container.Resolve<Class>(dictionary). But it did not work (config-args are used). Curiously if I use a anonymous type, it works.
Thanks in advance.
EDIT
public class TestB
{
public string A { get; set; }
public string B { get; set; }
public TestB(string a)
{
A = a;
//B = b;
}
}
[Test]
public void Test()
{
var dictionary = new Hashtable
{
{ "a", "b" }
};
var anonymousType = new
{
a = "b"
};
WindsorContainer container = new WindsorContainer(new XmlInterpreter());
var opt1 = container.Resolve<TestB>(anonymousType);
var opt2 = container.Resolve<TestB>(dictionary);
Assert.That(opt1.A == "b");
Assert.That(opt2.A == "b");
}
That’s freaky. Both assertions succeed. But if I swap opt1 and opt2 resolvations, assertion 2 fails.
The reason for that is that the dependency is set twice:
– first as a .ctor parameter
– then again as a property
Windsor does non-case-sensitive parameter name matching when matching your parameters from xml config and from anonymous type and the in-line argument you pass takes precedence over xml, just like you would expect.
However you gave it a
Hashtablethat you set up to be case-sensitive and Windsor honors that.So it matches
a.ctor argument, but then it goes to setAproperty, and theHashtabledoes not provide a value for that, so it grabs one from you XML.Regarding
You didn’t post your xml config but I suspect the lifestyle of the component is singleton, in which case the second call to
Resolvewill just give you the object constructed by the first call, and whatever arguments you pass will be ignored.Normally you probably would not expose setters for properties being set via .ctor and keep them readonly.