Until now I have done type registration inside a class within my MVC project but I am now trying to do it with Modules. My project is structured as follows
Project.Data: contains my entityframework classes and DataContext. I have refactored my datacontect to implement an interface (IDbContext) which I register via an autofac module Project.Business: contains business logic classes into which and IDbContext instance is injected. Classes implement corresponding interfaces which are also registered via an autofac module Project.Web: asp.net project which uses assembly scanning to register all autofac modules
Sample Code
Project.Data
//IDbContext
public interface IDbContext
{
IDbSet<MyData> MyDatas { get; set; }
....
}
//DataContext
public class DataContext : DbContext, IDbContext
{
public IDbSet<MyData> MyDatas { get; set; }
}
//Module
public class DataInjectionModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<DataContext>().As<IDbContext>();
}
}
Project.Business
public interface IServeDataService
{
IEnumerable<object> GetData();
}
public class ServeDataService : IServeDataService
{
private IDbContext context;
public ServeDataService()
{
this.context = context;
}
public IEnumerable<object> GetData()
{
}
}
public class BusinessInjectionModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ServeDataService>().As<IServeDataService>();
}
}
Project.Web
public partial class Startup
{
public void RegisterContainer()
{
var builder = new ContainerBuilder();
var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>();
builder.RegisterAssemblyModules(assemblies.ToArray());
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);
}
}
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
RegisterContainer();
}
}
//controller
public class DataController : ApiController
{
private IServeDataService dataService;
public DataController(IServeDataService dataService)
{
this.dataService = dataService;
}
public async Task<IHttpActionResult> Get()
{
var data = dataService.GetData();
return Ok(data);
}
}
however when I try to call the api service, I get the following error
An error occurred when trying to create a controller of type 'DataController'. Make sure that the controller has a parameterless public constructor.
I have debugged and set break points in the RegisterContainer methid and that gets called, I have also looked at the assemblies listed and my Business and Data assemblies are listed, but my module registrations are never run. What am I doing wrong?
It seems that you didn't configure Web API to use your Autofac container.
To get Autofac integrated with Web API you need to reference the Web API integration NuGet package, register your controllers, and set the dependency resolver. You can optionally enable other features as well.
> Autofac - Web API documentation.
In order to make it work you have to add a reference on the Autofac ASP.NET Web API Integration nuget package and add the following line in your RegisterContainer
method :
// Set the dependency resolver to be Autofac.
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);