Using Autofac With Web API

Introduction

In this article, we will describe how we can implement Dependency Injection (DI), using Autofac. The idea of this post is to show the steps to configure Autofac in Web API. In this example, we will create a Web API controller named customer and it contains only a Service, which is able to retrieve the data from the database.

What’s Autofac?

Autofac is an addictive IoC container for Microsoft .NET 4.5, Silverlight 5, Windows Store apps and Windows Phone 8 apps. It manages the dependencies between the classes, so that the applications stay easy to change, as they grow in size and complexity. This is achieved by treating regular .NET classes as the components.

autofac

Prerequisites

As I said before, to achieve our requirement, you must have Visual Studio 2015 (.NET Framework 4.5.2) and SQL Server.

In this article, we are going to

  • Create a database.
  • Create Web API Application.
  • Configure Entity Framework ORM.
  • Install Autofac.
  • Implement http Service.
  • Configure Autofac.

SQL database part

Here, you can find the scripts to create a database and table.

Create a database 

  1. USE [master]  
  2. GO  
  3.   
  4. /****** Object:  Database [DBCustomer]    Script Date: 3/19/2017 3:54:44 AM ******/  
  5. CREATE DATABASE [DBCustomer]  
  6.  CONTAINMENT = NONE  
  7.  ON  PRIMARY   
  8. NAME = N'DBCustomer', FILENAME = N'c:\Program Files (x86)\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\DBCustomer.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )  
  9.  LOG ON   
  10. NAME = N'DBCustomer_log', FILENAME = N'c:\Program Files (x86)\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\DBCustomer_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)  
  11. GO  
  12.   
  13. ALTER DATABASE [DBCustomer] SET COMPATIBILITY_LEVEL = 110  
  14. GO  
  15.   
  16. IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))  
  17. begin  
  18. EXEC [DBCustomer].[dbo].[sp_fulltext_database] @action = 'enable'  
  19. end  
  20. GO  
  21.   
  22. ALTER DATABASE [DBCustomer] SET ANSI_NULL_DEFAULT OFF   
  23. GO  
  24.   
  25. ALTER DATABASE [DBCustomer] SET ANSI_NULLS OFF   
  26. GO  
  27.   
  28. ALTER DATABASE [DBCustomer] SET ANSI_PADDING OFF   
  29. GO  
  30.   
  31. ALTER DATABASE [DBCustomer] SET ANSI_WARNINGS OFF   
  32. GO  
  33.   
  34. ALTER DATABASE [DBCustomer] SET ARITHABORT OFF   
  35. GO  
  36.   
  37. ALTER DATABASE [DBCustomer] SET AUTO_CLOSE OFF   
  38. GO  
  39.   
  40. ALTER DATABASE [DBCustomer] SET AUTO_CREATE_STATISTICS ON   
  41. GO  
  42.   
  43. ALTER DATABASE [DBCustomer] SET AUTO_SHRINK OFF   
  44. GO  
  45.   
  46. ALTER DATABASE [DBCustomer] SET AUTO_UPDATE_STATISTICS ON   
  47. GO  
  48.   
  49. ALTER DATABASE [DBCustomer] SET CURSOR_CLOSE_ON_COMMIT OFF   
  50. GO  
  51.   
  52. ALTER DATABASE [DBCustomer] SET CURSOR_DEFAULT  GLOBAL   
  53. GO  
  54.   
  55. ALTER DATABASE [DBCustomer] SET CONCAT_NULL_YIELDS_NULL OFF   
  56. GO  
  57.   
  58. ALTER DATABASE [DBCustomer] SET NUMERIC_ROUNDABORT OFF   
  59. GO  
  60.   
  61. ALTER DATABASE [DBCustomer] SET QUOTED_IDENTIFIER OFF   
  62. GO  
  63.   
  64. ALTER DATABASE [DBCustomer] SET RECURSIVE_TRIGGERS OFF   
  65. GO  
  66.   
  67. ALTER DATABASE [DBCustomer] SET  DISABLE_BROKER   
  68. GO  
  69.   
  70. ALTER DATABASE [DBCustomer] SET AUTO_UPDATE_STATISTICS_ASYNC OFF   
  71. GO  
  72.   
  73. ALTER DATABASE [DBCustomer] SET DATE_CORRELATION_OPTIMIZATION OFF   
  74. GO  
  75.   
  76. ALTER DATABASE [DBCustomer] SET TRUSTWORTHY OFF   
  77. GO  
  78.   
  79. ALTER DATABASE [DBCustomer] SET ALLOW_SNAPSHOT_ISOLATION OFF   
  80. GO  
  81.   
  82. ALTER DATABASE [DBCustomer] SET PARAMETERIZATION SIMPLE   
  83. GO  
  84.   
  85. ALTER DATABASE [DBCustomer] SET READ_COMMITTED_SNAPSHOT OFF   
  86. GO  
  87.   
  88. ALTER DATABASE [DBCustomer] SET HONOR_BROKER_PRIORITY OFF   
  89. GO  
  90.   
  91. ALTER DATABASE [DBCustomer] SET RECOVERY SIMPLE   
  92. GO  
  93.   
  94. ALTER DATABASE [DBCustomer] SET  MULTI_USER   
  95. GO  
  96.   
  97. ALTER DATABASE [DBCustomer] SET PAGE_VERIFY CHECKSUM    
  98. GO  
  99.   
  100. ALTER DATABASE [DBCustomer] SET DB_CHAINING OFF   
  101. GO  
  102.   
  103. ALTER DATABASE [DBCustomer] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF )   
  104. GO  
  105.   
  106. ALTER DATABASE [DBCustomer] SET TARGET_RECOVERY_TIME = 0 SECONDS   
  107. GO  
  108.   
  109. ALTER DATABASE [DBCustomer] SET  READ_WRITE   
  110. GO  
  111. Create Tables  
  112.   
  113. USE [DBCustomer]  
  114. GO  
  115.   
  116. /****** Object:  Table [dbo].[Customer]    Script Date: 3/19/2017 3:55:15 AM ******/  
  117. SET ANSI_NULLS ON  
  118. GO  
  119.   
  120. SET QUOTED_IDENTIFIER ON  
  121. GO  
  122.   
  123. SET ANSI_PADDING ON  
  124. GO  
  125.   
  126. CREATE TABLE [dbo].[Customer](  
  127.     [CustID] [int] IDENTITY(1,1) NOT NULL,  
  128.     [FirstName] [varchar](50) NULL,  
  129.     [LastName] [varchar](50) NULL,  
  130.     [Email] [varchar](50) NULL,  
  131.     [Country] [varchar](50) NULL,  
  132.  CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED   
  133. (  
  134.     [CustID] ASC  
  135. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ONON [PRIMARY]  
  136. ON [PRIMARY]  
  137.   
  138. GO  
  139.   
  140. SET ANSI_PADDING OFF  
  141. GO   

Create your MVC application

Open Visual Studio and select File >> New Project.

New Project Window will pop up. Select ASP.NET Web Application (.NET Framework), name your project and click OK.

ASP.NET

Now, new dialog will pop up to select the template. We are going to choose Web API template and click OK button.

ASP.NET

Now, we need to create a class library. To do this, right click on the project name > Add > New Item > select class library.

ASP.NET

After creating our class library, we are going to add ADO.NET Entity Data Model.

Adding ADO.NET Entity Data Model

For this, right click on the class library name, click Add > Add New Item. The dialog box will pop up inside Visual C#, select Data, followed by ADO.NET Entity Data Model and enter the name for your DbContext model as CustomerModel. finally click Add.

ASP.NET

At this stage, we are going to choose EF Designer from the database, as given below.

ASP.NET

In the snapshot given below, we need to select your Server name, then via dropdown list in connect to a database section, you should choose your database name, finally click OK button.

ASP.NET

ASP.NET

As given above, the dialog Entity Data Model Wizard will pop up to choose an object, which is used in the demo. In this example, we are going to select Customer table and click Finish button.

Finally, we see that EDMX model generates Customer entity, as shown below.

ASP.NET

Now, we are going to create generic repository, which contains the method used to return all the data from customer table. I would like to say that the following repository can also include any other methods like (CRUD, etc.)

First of all, we are creating Db Factory class, which returns the instance of DbContext.

IDbFactory.cs 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6.   
  7. namespace AutoFacWithWebAPI.Repository.Common  
  8. {  
  9.    public interface IDbFactory  
  10.     {  
  11.         DBCustomerEntities Init();  
  12.     }  
  13. }   

DbFactory.cs 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6.   
  7. namespace AutoFacWithWebAPI.Repository.Common  
  8. {  
  9.     public class DbFactory : IDbFactory  
  10.     {  
  11.         DBCustomerEntities dbContext;  
  12.   
  13.         public DBCustomerEntities Init()  
  14.         {  
  15.             return dbContext ?? (dbContext = new DBCustomerEntities());  
  16.         }  
  17.     }  
  18. }   

IGenericRepository.cs 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6.   
  7. namespace AutoFacWithWebAPI.Repository.Common  
  8. {  
  9.    public interface IGenericRepository<T> where T : class  
  10.     {  
  11.         IQueryable<T> GetAll();  
  12.     }  
  13. }   

GenericRepository.cs 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6.   
  7. namespace AutoFacWithWebAPI.Repository.Common  
  8. {  
  9.     public class GenericRepository<T> : IGenericRepository<T> where T : class  
  10.     {  
  11.   
  12.         private DBCustomerEntities dbContext;  
  13.   
  14.         protected IDbFactory DbFactory  
  15.         {  
  16.             get;  
  17.             private set;  
  18.         }  
  19.   
  20.         protected DBCustomerEntities DbContext  
  21.         {  
  22.             get { return dbContext ?? (dbContext = DbFactory.Init()); }  
  23.         }  
  24.   
  25.         public GenericRepository(IDbFactory dbFactory)  
  26.         {  
  27.             DbFactory = dbFactory;  
  28.         }  
  29.   
  30.         public IQueryable<T> GetAll()  
  31.         {  
  32.             return DbContext.Set<T>();  
  33.         }  
  34.     }  
  35. }   

After implementing generic repository, we are adding reference of our class library to Web API project. To do this, right click on References > Add Reference.

ASP.NET

Installing Autofac

It’s simple to add Autofac. We can do this by using NuGet Packages or Package Manager Console. In this example, I used NuGet Packages. Thus, right click on References > Manage NuGet Packages.

First, we are installing Autofac. Subsequently, install Autofac.integration.WebAPI, as shown below.

ASP.NET

ASP.NET

Note

Please make sure that the references given below have been added successfully.

ASP.NET

Create a controller

Now, we are going to create a controller. Right click on the controllers folder > Add > Controller> selecting Web API 2 Controller – Empty > click Add.

ASP.NET

Enter Controller name (‘CustomerController’).

ASP.NET

CustomerController.cs 

  1. using AutoFacWithWebAPI.Repository;  
  2. using AutoFacWithWebAPI.Repository.Common;  
  3. using System;  
  4. using System.Collections.Generic;  
  5. using System.Linq;  
  6. using System.Net;  
  7. using System.Net.Http;  
  8. using System.Web.Http;  
  9.   
  10. namespace AutoFacWithWebAPI.Controllers  
  11. {  
  12.     public class CustomerController : ApiController  
  13.     {  
  14.         private readonly IGenericRepository<Customer> _customerRepository;  
  15.   
  16.         public CustomerController(IGenericRepository<Customer> customerRepository)  
  17.         {  
  18.             _customerRepository = customerRepository;  
  19.         }  
  20.   
  21.         public IQueryable<Customer> GetCustomerList()  
  22.         {  
  23.             return _customerRepository.GetAll();  
  24.         }  
  25.   
  26.     }  
  27. }   

As you can see, we have injected our customer repository within constructor, and then we have defined method called Get Customer List which returns Customer list.

Configuring Autofac

At this point, from Solution Explorer section, we are going to add 2 classes, as shown below.

AutofacWebapiConfig.cs 

  1. using Autofac;  
  2. using Autofac.Integration.WebApi;  
  3. using AutoFacWithWebAPI.Repository;  
  4. using AutoFacWithWebAPI.Repository.Common;  
  5. using System;  
  6. using System.Collections.Generic;  
  7. using System.Data.Entity;  
  8. using System.Linq;  
  9. using System.Reflection;  
  10. using System.Web;  
  11. using System.Web.Http;  
  12.   
  13. namespace AutoFacWithWebAPI.App_Start  
  14. {  
  15.     public class AutofacWebapiConfig  
  16.     {  
  17.   
  18.         public static IContainer Container;  
  19.   
  20.         public static void Initialize(HttpConfiguration config)  
  21.         {  
  22.             Initialize(config, RegisterServices(new ContainerBuilder()));  
  23.         }  
  24.   
  25.   
  26.         public static void Initialize(HttpConfiguration config, IContainer container)  
  27.         {  
  28.             config.DependencyResolver = new AutofacWebApiDependencyResolver(container);  
  29.         }  
  30.   
  31.         private static IContainer RegisterServices(ContainerBuilder builder)  
  32.         {  
  33.             //Register your Web API controllers.  
  34.             builder.RegisterApiControllers(Assembly.GetExecutingAssembly());  
  35.   
  36.             builder.RegisterType<DBCustomerEntities>()  
  37.                    .As<DbContext>()  
  38.                    .InstancePerRequest();  
  39.   
  40.             builder.RegisterType<DbFactory>()  
  41.                    .As<IDbFactory>()  
  42.                    .InstancePerRequest();  
  43.   
  44.             builder.RegisterGeneric(typeof(GenericRepository<>))  
  45.                    .As(typeof(IGenericRepository<>))  
  46.                    .InstancePerRequest();  
  47.   
  48.             //Set the dependency resolver to be Autofac.  
  49.             Container = builder.Build();  
  50.   
  51.             return Container;  
  52.         }  
  53.   
  54.     }  
  55. }   

Here, you register the components with Autofac by creating a container builder, which components expose, which services.

In RegisterServices() method, we have registered all the needed types that expose interfaces. Now, build the container to finalize the registrations and prepare for the object resolution.

In Initialize() method, after building your container, we need to pass it into new instance of the AutofacWebApiDependencyResolver class. Attach the new resolver to your config.DependencyResolver to allow Web API know that it should locate the Services, using the AutofacWebApiDependencyResolver.

Bootstrapper.cs 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Http;  
  6.   
  7. namespace AutoFacWithWebAPI.App_Start  
  8. {  
  9.     public class Bootstrapper  
  10.     {  
  11.   
  12.        public static void Run()  
  13.         {  
  14.             //Configure AutoFac  
  15.             AutofacWebapiConfig.Initialize(GlobalConfiguration.Configuration);  
  16.         }  
  17.   
  18.     }  
  19. }   

Note

Please make sure that Run() has been added in Application_Start() method.

Global.asax.cs 

  1. using AutoFacWithWebAPI.App_Start;  
  2. using System;  
  3. using System.Collections.Generic;  
  4. using System.Linq;  
  5. using System.Web;  
  6. using System.Web.Http;  
  7. using System.Web.Mvc;  
  8. using System.Web.Optimization;  
  9. using System.Web.Routing;  
  10.   
  11. namespace AutoFacWithWebAPI  
  12. {  
  13.     public class WebApiApplication : System.Web.HttpApplication  
  14.     {  
  15.         protected void Application_Start()  
  16.         {  
  17.   
  18.   
  19.             AreaRegistration.RegisterAllAreas();  
  20.               
  21.             Bootstrapper.Run();  
  22.   
  23.             GlobalConfiguration.Configure(WebApiConfig.Register);  
  24.             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);  
  25.             RouteConfig.RegisterRoutes(RouteTable.Routes);  
  26.             BundleConfig.RegisterBundles(BundleTable.Bundles);  
  27.         }  
  28.     }  
  29. }   

Output

Now, you can run your Application and let’s see the output.

ASP.NET