I'm new to Inversion of Control & Autofac. Going through the documentation, there is a lot ASP.NET Web Api concepts I do not fully understand or have experience with, making it a bit difficult to determine what is missing from my implementation.
I want to apply Autofac to an existing ASP.NET Web Api project that has several ApiControllers. These controllers all share a parent abstract class. This abstract class has a method that is responsible for returning an instance of a service. I hoped to replace this method with Autofac's dependency injection.
The parent abstract class from which every ApiController inherits, is very simple.
public abstract class BaseApiController
{
public IMyService serviceClient { get; set; }
public BaseApiController() {}
public BaseApiController(IMyService serviceClient)
{
this.serviceClient = serviceClient;
}
}
Every controller inherits from the above class, while some employs a default Get method, most have multiple routes. Not a single controller is specifying a constructor:
public class MyController : BaseApiController
{
public MyController() : base() {}
public MyController(IMyService serviceClient) : base(serviceClient) {}
[HttpGet]
[Route("api/foo/bar")]
[ActionName("FooBar")]
public string FooBar()
{
using (serviceClient)
{
return serviceClient.GetFooBar() as string;
}
}
}
Autofac is integrated into the Application_Start method of the applications Glabal.asax.cs, registering the ServerClientProvider which should be the provider that should be resolved to when a dependency to the IMyService is encountered:
public class Global : System.Web.HttpApplication, IContainerProviderAccessor
{
#region AutoFac
private static IContainerProvider _containerProvider;
public IContainerProvider ContainerProvider => _containerProvider;
#endregion AutoFac
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.Register(x => ServiceClientProvider.GetServiceClient())
.As<IMyService>()
.InstancePerRequest();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
builder.RegisterHubs(Assembly.GetExecutingAssembly()).PropertiesAutowired();
var container = builder.Build();
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
GlobalHost.DependencyResolver = new AutofacDependencyResolver(container);
_containerProvider = new ContainerProvider(container);
}
}
I have configured the ASP.NET application, in the web.config:
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="ContainerDisposal" type="Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web" preCondition="managedHandler" />
<add name="PropertyInjection" type="Autofac.Integration.Web.Forms.PropertyInjectionModule, Autofac.Integration.Web" preCondition="managedHandler" />
</modules>
</system.webServer>
<configuration>
As I understand it, Autofac should automatically resolve the provider when encountering a controller with a public property that matches the registered type (Property Injection), or if a constructor exists with a parameter that matches any registered dependency.
However, I'm not getting any errors relating to my Autofac configuration. I'm getting a NullReferenceException when the MyController attempt to call the IMyService.FooBar method.
What am I missing?
Any help would be greatly appreciated.