Following the answer from this other post I am trying to configure autofac for both an ASP .Net MVC 5 project and a Web Api 2 one.
For the Web Api project I used the Autofac.Integration.WebApi library that I referenced it manually to the project and modified the Global.asax file like so:
public class WebApiApplication : HttpApplication
{
protected void Application_Start()
{
ConfigureDiContainer();
GlobalConfiguration.Configure(WebApiConfig.Register);
}
private static void ConfigureDiContainer()
{
var servicesAssembly = Assembly.GetExecutingAssembly();
var container = BuildContainer(servicesAssembly);
var resolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
private static IContainer BuildContainer(Assembly servicesAssembly)
{
var x = new ActivityBl();
var builder = new ContainerBuilder();
builder.RegisterApiControllers(servicesAssembly);
var appAssemblies = AppDomain.CurrentDomain
.GetAssemblies()
.Where(a => a.ToString().StartsWith("SC."))
.ToArray();
builder.RegisterAssemblyTypes(appAssemblies).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(servicesAssembly).AsImplementedInterfaces();
return builder.Build();
}
}
And when I run the services this works as expected.
For the MVC 5 project I installed the Autofac.Integration.Mvc library from NuGet and modified the Global.asax code as well:
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
The controllers in both projects have no default constructor, only the ones with the dependencies:
MVC Controller:
private readonly IActivitiesService activitiesService;
public HomeController(IActivitiesService activitiesService)
{
this.activitiesService = activitiesService;
}
Web Api Controller:
public class ActivitiesController : ApiController, IActivitiesService
{
private readonly IActivities activitiesBl;
public ActivitiesController(IActivities activitiesBl)
{
if(activitiesBl == null) throw new ArgumentNullException("activitiesBl", "ActivitiesBl dependency was not properly created.");
this.activitiesBl = activitiesBl;
}
}
When I run the application I get the following error:
None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'SC.Web.Controllers.HomeController' can be invoked with the available services and parameters: Cannot resolve parameter 'SC.Services.ServiceContracts.IActivitiesService activitiesService' of constructor 'Void .ctor(SC.Services.ServiceContracts.IActivitiesService)'.
In a way I guess it makes sense since the IoC on the web project has no definitions for the services and it seems that it is trying to resolve the whole dependency tree which leads me to the following questions:
- From the names of the libraries it seems that each one is specifically tailored for each kind of project, is that so or can I use the Mvc one also for the Web Api?
- Have things changed in such a way that the recommendation I got from the previous post is no longer valid and now I must have all the definitions in the Composition Root for each client?
- What would be now the best way of configuring the dependencies hierarchy in this kind of multi-layered setup?
Thank you.