Search code examples
c#asp.net-mvcdependency-injectionoptional-parameters

Dependency Injection Optional Parameters


Is it considered a bad practice to use optional parameters when using dependency injection frameworks with Constructor injection?

Example:

public class ProductsController
{
    public ProductsController(IProductService productService = null, IBackOrderService = null)
    {
    }
}

I have specified both parameters as optional, but my DI framework will always inject both dependencies. If I add a new action to my controller which requires a new dependency, would it be bad to make the new dependency optional? I could potentially be breaking dozens of unit tests even though the existing tests wouldn't require the new dependency.

Edit
People seem to be confused by my question. I am never construcing a ProductsController manually in my web application. This is handled by a controller factory (which automatically injects dependencies).

What I don't like is having a unit test like this:

[Test]
public void Test1()
{
    var controller = new ProductsController(new MockProductService(), new MockBackOrderService());
}

Now I decide to add a new action method to my controller. This new action needs a new dependency but none of the existing actions do. Now I have to go back and modify 100 different unit tests because I added a new parameter. I can avoid that by making the parameters optional, but I wanted to know if it was a bad idea. My gut feeling says no because the only thing it affects are the unit tests.


Solution

  • I don't think it's a good idea. Constructor injection means that the dependencies are required. You should even add the guard lines that throws if one of the parameters is null.

    I think the problem is with your unit tests. For instance I have only one place where the controller is created and supporting objects are mocked (controllerContext, HttpContext, Request, Response, etc.). Then if I add a new parameter in the constructor I have to change it only in one place in the unit tests.

    Maybe you should consider to code a generic base class in your unit tests, or make a usage of "setup" routine for the tests.