I have the following packages and their dependencies installed in my WebAPI project:
Ninject.Web.WebApi
Ninject.Web.WebApi.OwinHost
Make sure you have registered all the types used by the controller, all the way down to the database.
In my case, I had only added the interface that the controller itself used, but not the interface used to actually query the database.
Notice in the code below how the AddUserMaintenanceProcessor class has dependencies that the controller does not know about. If you omit the Unity (or whatever IoC tool you use) type mappings for these dependencies, the controller construction will fail.
My solution uses Unity, but the point I'm trying to make is that you need to create type mappings for all dependencies.
Startup.cs
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
// Configure Unity
var resolver = new UnityDependencyResolver(UnityConfig.GetConfiguredContainer());
GlobalConfiguration.Configuration.DependencyResolver = resolver;
config.DependencyResolver = resolver;
// Do Web API configuration
WebApiConfig.Register(config);
app.UseWebApi(config);
}
UnityConfig.cs
public class UnityConfig
{
private static readonly Lazy Container = new Lazy(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
// Gets the configured Unity container
public static IUnityContainer GetConfiguredContainer()
{
return Container.Value;
}
// Register type mappings
public static void RegisterTypes(IUnityContainer container)
{
// LogManagerAdapter wrapping e.g. log4net
container.RegisterType();
// AutoMapperAdapter wrapping e.g. AutoMapper (configuration omitted)
container.RegisterType();
// Interface for persisting the user
container.RegisterType();
// Interface for doing application logic in regards to adding a user
container.RegisterType();
}
}
UsersController.cs
public class UsersController : ApiController
{
private readonly IAddUserMaintenanceProcessor _addUserProcessor;
public UsersV1Controller(IAddUserMaintenanceProcessor addUserProcessor)
{
_addUserProcessor = addUserProcessor;
}
public async Task Post(NewUser user)
{
return await _addUserProcessor.AddUserAsync(user);
}
// ...
}
AddUserMaintenanceProcessor.cs
public class AddUserMaintenanceProcessor : IAddUserMaintenanceProcessor
{
private readonly IAddUserQueryProcessor _queryProcessor;
private readonly ILog _logger;
private readonly IAutoMapper _mapper;
public AddUserMaintenanceProcessor(
IAddUserQueryProcessor queryProcessor,
ILogManager logManager,
IAutoMapper mapper)
{
_queryProcessor = queryProcessor;
_logger = logManager.GetLog(typeof(AddUserMaintenanceProcessor));
_mapper = mapper;
}
public async Task AddUserAsync(NewUser newUser)
{
_logger.Info($"Adding new user {newUser.UserName}");
// Map the NewUser object to a User object
var user = _mapper.Map(newUser);
// Persist the user to a medium unknown to this class, using the query processor,
// which in turn returns a User object
var addedUser = await _queryProcessor.AddUserAsync(user);
// Map the User object back to UserModel to return to requester
var userModel = _mapper.Map(addedUser);
_logger.Info($"User {userModel.UserName} added successfully");
return userModel;
}
}
I have omitted the interfaces for the processors as they only contain one method (Strategy pattern). The interfaces for logging and auto mapping are irrelevant to this question.
The AddUserQueryProcessor class simply persists the user to the database. Once again irrelevant to this question.