Jeff
Jeff

Reputation: 36573

Windsor Optional Constructor Parameters

How can I have Windsor respect optional constructor parameters for injection?

I tried making an IContributeComponentModelConstruction that loops through each ParameterInfo of each constructor and checks if it IsOptional, then sets IsOptional on the Windsor Dependency object accordingly, but this doesn't seem to do the trick. I still get a "Could not instantiate because of dependency...etc.".

Thanks.

UPDATE:

I'm using 2.5.2.0 for Silverlight 4.0 and can reproduce with the following:

    var container = new WindsorContainer();
    container.Register(Component.For<TestClass>());
    container.Resolve<TestClass>(); //boom

    public class TestClass
    {
        public TestClass(ITest test=null)
        {

        }
    }

    public interface ITest
    {

    }


Missing dependency.
Component TestClass has a dependency on ITest, which could not be resolved.
Make sure the dependency is correctly registered in the container as a service, or provided as inline argument.

Upvotes: 2

Views: 2485

Answers (1)

Krzysztof Kozmic
Krzysztof Kozmic

Reputation: 27374

It does in v2.5.2.

update I had a look and ran the code you pasted and you're right it's not working. Windsor does correctly recognise that the parameter has a default value. However Windsor has also a second rule, that null is never a valid value for a required dependency, and this second rule wins in your case.

This should probably be considered a bug.

To make it work you will need to replace the DefaultDependencyResolver with your own.

You'll need to override two methods: from DefaultDependencyResolver pretty much like this:

public class AllowDefaultNullResolver : DefaultDependencyResolver
{
    protected override bool CanResolveServiceDependency(CreationContext context, ComponentModel model, DependencyModel dependency)
    {
        return base.CanResolveServiceDependency(context, model, dependency) || dependency.HasDefaultValue;
    }

    protected override object ResolveServiceDependency(CreationContext context, ComponentModel model, DependencyModel dependency)
    {
        try
        {
            return base.ResolveServiceDependency(context, model, dependency);
        }
        catch (DependencyResolverException)
        {
            if(dependency.HasDefaultValue)
            {
                return dependency.DefaultValue;
            }
            throw;
        }
    }
}

and use this resolver instead of the default one.

Upvotes: 2

Related Questions