I have a C# MVC
project using Repository Pattern
and Ninject
(DI). All is working fine.
Inside a Repository Im instantiating a class to process some calls to external APIs like this:
public class EmployeeRepository : IEmployeeRepository
{
private readonly AppState _appState;
public EmployeeRepository(IAppStateProvider appStateProvider)
{
_appState = appStateProvider.AppState;
}
public bool ProcessEmployee(long employeeId, object data)
{
var api = new ExternalAPI(_appState);
api.PostData(data);
return true;
}
}
Then my ExternalAPI.cs
class is:
public class ExternalAPI: BaseRepository
{
[Inject]
public ILogRepository Logger { get; set; }
private readonly AppState _appState;
public ExternalAPI(AppState appState)
{
_appState = appState;
}
private bool PostData(object data)
{
bool returnVal = true;
// Some code here....
Logger.InsertLog(data); // HERE Logger IS NULL
return returnVal;
}
}
I get an exception here because Logger
is null
.
And in my main project NinjectWebCommon.cs
file Im registering the dependency correctly:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind(typeof(ILogRepository)).To(typeof(Data.LogRepository));
}
Any clue why the
[Inject]
ofILogRepository
is not working in theExternalAPI
class?
Maybe because from EmployeeRepository Im creating a new instance of that class:
var api = new ExternalAPI(_appState);
Any advice and how can I make the injection of
ILogRepository
work inExternalAPI
class?
Reference Explicit Dependencies Principle
Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.
ExternalAPI
is dependent on ILogRepository
and AppState
so that is what should be injected into it
public class ExternalAPI: BaseRepository, IExternalAPI {
private readonly ILogRepository logger;
private readonly AppState _appState;
public ExternalAPI(IAppStateProvider appStateProvidere, ILogRepository logger) {
_appState = appStateProvidere.AppState;
this.logger = logger;
}
public bool PostData(object data) {
bool returnVal = true;
// Some code here....
logger.InsertLog(data); // HERE Logger IS NULL
return returnVal;
}
}
EmployeeRepository
is dependent on ExternalAPI
so that is what should be injected into it.
public class EmployeeRepository : IEmployeeRepository {
private readonly IExternalAPI api;
public EmployeeRepository(IExternalAPI api) {
this.api = api;
}
public bool ProcessEmployee(long employeeId, object data) {
api.PostData(data);
return true;
}
}
Ensure that any necessary dependencies are registered with the container
private static void RegisterServices(IKernel kernel) {
//...
kernel.Bind(typeof(ILogRepository)).To(typeof(Data.LogRepository));
kernel.Bind(typeof(IExternalAPI)).To(typeof(ExternalAPI));
//...
}