Reputation: 1129
I'm trying to add ninject to the following setup -
public class BaseController : Controller
{
protected ILogger Logger {get;}
public BaseController() { Logger = new MyLogger(); }
}
public class Controller1Controller : BaseController { ... }
public class Controller2Controller : BaseController { ... }
....
public class ControllerNController : BaseController { ... }
With ninject, adding an ILogger parameter to BaseController works great -
public class BaseController : Controller
{
protected ILogger Logger {get;}
public BaseController(ILogger logger) { Logger = logger; }
}
but now it also requires adding a constructor in each of the child controllers because the base class no longer has a parameterless constructor-
public class Controller1Controller : BaseController {
public Controller1Controller(ILogger logger) : base(logger) { }
}
There are over 50 child controllers and going forward it might become a bit of a maintenance problem if we have to add/remove more dependencies. Further, the code being added to each controller is exactly the same.
Is there a way to keep the child controllers as they are (without any constructors) but still make that change to the BaseController?
Upvotes: 2
Views: 790
Reputation: 96
Sorry but no.
As an alternative solution you can get ILogger from Ninject: Using property injection instead of constructor injection
Upvotes: 1
Reputation: 3948
Simple answer: No (You have to update your derived class constructors)
Explanation: For injected instance of ILogger to be passed across derived and base classes, you need to update your derived constructors with ILogger parameter and then forward the parameter to the base. Unless, there is a wiser solution to this situation.
See the first point in disadvantages section on wiki DI Disadvantages (DI comes with this baggage)
Additionally: You can create a protected member in the base class to hold the ILogger instance, which will make this protected instance accessible to all the derived classes.
Update: Partially agree with tomludd's solution of using Property injection. See this SO answer. For more DI techniques, please do read articles/blogs from Mark Seemann or his book DI in .NET
Upvotes: 1
Reputation: 2885
Try this in BaseController constructor
public BaseController(ILogger logger = null)
{
if (logger != null)
Logger = logger;
else
Logger = new MyLogger();
}
Upvotes: 0