TypedFactoryFacility: Passing null argument
Consider the following test:
[Test]
public void Create_ServiceWithDynamicDependency_Created()
{
// arrange
IWindsorContainer container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IServiceFactory>().AsFactory());
container.Register(Component.For<ServiceWithDynamicDependency>().LifeStyle.Transient);
container.Register(Component.For<SomethingStatic>().LifeStyle.Transient);
var factory = container.Resolve<IServiceFactory>();
// act
ServiceWithDynamicDependency serviceWithDynamicDependency = factory.Create(null);
// assert
Assert.That(serviceWithDynamicDependency, Is.Not.Null);
}
This fails with the following exception: Could not resolve non-optional dependency for 'Testing.Windsor.Factory.ServiceWithDynamicDependency' (Testing.Windsor.Factory.ServiceWithDynamicDependency). Parameter 'somethingDynamic' type 'System.String'
If I replace the assert part with this:
ServiceWithDynamicDependency serviceWithDynamicDependency = factory.Create("foo");
The component is resolved a开发者_如何学Pythons expected. Does anyone know of a workaround for this or do I have to hand-roll factories which accepts null arguments?
Although you didn't specify it I'm assuming your component has one constructor that looks like this:
public ServiceWithDynamicDependency(string somethingDynamic) {}
The behavior you're observing is not a bug - this is by design, and here's why.
If a value is required an actual value has to be provided, and null
is not considered to be a correct value. Otherwise Windsor would just be passing null
in for every constructor instead of bothering to find actual dependencies for that.
null
is a special value in .NET and it means "no value". So even though you explicitly provide null
as an argument Windsor will ignore it.
To solve this, instead of working around be explicit that the value is optional and provide a second constructor that does not include it.
Windsor is smart enough to pick the right constructor and if the value is not provided (or null as in your case) it will pick the no-argument constructor, and when the value is there (is not null) it will pick the one with the value.
精彩评论