Using default parameter values with Ninject 3.0
Asked Answered
W

2

12

I have a class with a constructor having a parameter with a default value. With Ninject 2.2, it would honor the [Optional] attribute and work fine with no binding defined against a constructor declared like so:

public EmployeeValidator([Optional] IValidator<PersonName> personNameValidator = null)

Since upgrading to Ninject 3.0, construction of this object fails with a message stating that the provider returned null:

Test method ValidatorIsolated.Tests.EmployeeValidatorTest.CreateEmployeeValidatorTest threw exception:

Ninject.ActivationException: Error activating IValidator{PersonName} using conditional implicit self-binding of IValidator{PersonName}

Provider returned null.

Activation path:

2) Injection of dependency IValidator{PersonName} into parameter personNameValidator of constructor of type EmployeeValidator

1) Request for IValidator{Employee}

Suggestions:

1) Ensure that the provider handles creation requests properly.

Is the [Optional] attribute still honored when a default value for a parameter is present and what is the best way to handle injection with optional parameters such as this?

Weakminded answered 9/5, 2012 at 14:16 Comment(0)
B
17

The Optional Attribute is ignored in this situation because there is always the default value available- But the provided value is null. Null is not an allowed value by default.

You can override this behavior by setting NinjectSettings.AllowNullInjection to true.

Bradfield answered 9/5, 2012 at 15:57 Comment(2)
@The Davester: Smells like a pull request for an improvement to an error message :PBelfry
The NinjectSettings.AllowNullInjection is generally the `kernel.Settings' property for those assuming it's a static property.Escaut
K
2

You can avoid setting AllowNullInjection globally while still injecting a parameter only when a binding exists by configuring your binding like this:

Kernel.Bind<IEmployeeValidator>()
      .To<EmployeeValidator>()
      .WithConstructorArgument(typeof(IValidator<PersonName>), c => c.Kernel.TryGet<IValidator<PersonName>>());

[Optional] is not needed for that.

Kolomna answered 3/12, 2019 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.