Cybercrux

Everything is achievable through technology

autofac Web api

ASP.NET Web API has nearly the same Dependency Injection support as ASP.NET MVC. As we do not have a built in support for ASP.NET Web API in Autofac (yet), I created a simple one. The implementation is not as straight forward as Ninject and you probably saw the below error if you tried to make it work:

System.InvalidOperationException:

An error occurred when trying to create a controller of type ‘TourismDictionary.APIs.Controllers.WordsController‘. Make sure that the controller has a parameterless public constructor.

Let’s see how it works:

First I created a class which implements System.Web.Http.Services.IDependencyResolver interface.

internal class AutofacWebAPIDependencyResolver : 
    System.Web.Http.Services.IDependencyResolver {

    private readonly IContainer _container;

    public AutofacWebAPIDependencyResolver(IContainer container) {

        _container = container;
    }

    public object GetService(Type serviceType) {

        return 
            _container.IsRegistered(serviceType) ? 
            _container.Resolve(serviceType) : null;
    }

    public IEnumerable<object> GetServices(Type serviceType) {

        Type enumerableServiceType = 
            typeof(IEnumerable<>).MakeGenericType(serviceType);
            
        object instance = 
            _container.Resolve(enumerableServiceType);
            
        return ((IEnumerable)instance).Cast<object>();
    }
}

And I have another class which holds my registrations and sets the ServiceResolver with GlobalConfiguration.Configuration.ServiceResolver.SetResolver method which is equivalent to DependencyResolver.SetResolver method:

internal class AutofacWebAPI {

    public static void Initialize() {
        var builder = new ContainerBuilder();
        GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
            new AutofacWebAPIDependencyResolver(RegisterServices(builder))
        );
    }

    private static IContainer RegisterServices(ContainerBuilder builder) {

        builder.RegisterAssemblyTypes(
            typeof(MvcApplication).Assembly
        ).PropertiesAutowired();

        //deal with your dependencies here
        builder.RegisterType<WordRepository>().As<IWordRepository>();
        builder.RegisterType<MeaningRepository>().As<IMeaningRepository>();

        return
            builder.Build();
    }
}

Then, initialize it at Application_Start:

public class MvcApplication : System.Web.HttpApplication {

    private void Configure(HttpConfiguration httpConfiguration) {

        httpConfiguration.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }

    protected void Application_Start() {

        Configure(GlobalConfiguration.Configuration);
        AutofacWebAPI.Initialize();
    }

}

There are different ways of doing it

Leave a comment