Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Dependency Injection Pattern with Autofac

4.92/5 (23 votes)
13 Dec 2013CPOL3 min read 77.1K   9  
How Dependency Injection (DI) can help us build a loosely coupled software architecture, and how to implement DI using Autofac.

Introduction

The Dependency Injection pattern, also known as Inversion of Control, is one of the most popular design paradigms today. It enables us to write loosely coupled code, it eliminates tight coupling between objects to make both the objects and applications that use them more flexible, reusable, easier to test, and makes it possible to change them at runtime and compile time. 

In this article, we will discuss how Dependency Injection (DI) can help us build a loosely coupled software architecture, and how to implement DI using Autofac. By the end of the article, we should be clear about the pattern and how to apply it in an ASP.NET MVC4 application. 

Technology: Visual Studio 2012, .NET Framework 4.5, ASP.NET MVC4, Entity Framework 5, and C#. 

Background 

There are four primary ways in which we can inject dependency to a class, such as Constructor injection, Setter injection, Property injection, and Method injection. In this article, I will discuss about Constructor injection and how to implement DI using Autofac.

Constructor Injection: This is the most common DI. In this methodology we pass the object reference in the constructor itself. So when the client creates the object, it passes the object in the constructor. Dependency Injection is done by supplying the dependency through the class’ constructor when instantiating that class. The injected component can be used anywhere within the class. 

C#
public class Customer     
{
    DIDbContext dbContext = new DIDbContext();
    public int Create(Customer customer)
    {
        if (customer != null)
        {
            dbContext.Customers.Add(customer);
            dbContext.SaveChanges();
            return 1;
        }
        return 0;
    }
    public IEnumerable<customer> GetAllCustomers()
    {
        return dbContext.Customers.ToList();
    }
}

public class CustomerController : Controller
{
    Customer customer = null;
    public CustomerController()
    {
        Customer=new Customer();
    }
    public ActionResult Index()
    {
       var customers= customer.GetAllCustomers();
       return View(customers);
    }
    public ActionResult Create()
    {           
        return View();
    }
    [HttpPost]
    public ActionResult Create(Customer customer)
    {
         customer.Create(customer);
        return RedirectToAction("Index"); 
    }
}

The CustomerController class has a dependency on the Customer class. In this case, the CustomerController creates an instance of the Customer directly inside of the CustomerController constructor and knows exactly what kind of customer class it’s creating and consuming. It does violate DIP.

To reduce dependency we have to do a couple of steps. Firstly we introduce the Repository layer where we can keep database related functionality such as data insert, modify, and get. Then we introduce the service layer, where we can keep extra logic if we need. For example, if we need to send a mail to the customer or if we need to calculate the total profit from the customer. In this case we can keep mail sending and calculation functionality in the service layer. We can make two abstraction layers between Customer and CustomerController. We can use the interface/abstract class to represent the abstractions between the Customer and CustomerController.

C#
public interface IRepository<t>
{
    int Create(T t);
    IEnumerable<t> FindAll();
    T FindById(int id);
}

public class CustomerRepository : IRepository<customer>
{
    DIDbContext dbContext = new DIDbContext();

    public int Create(Customer customer)
    {
        if (customer != null)
        {
            dbContext.Customers.Add(customer);
            dbContext.SaveChanges();
            return 1;
        }
        return 0;
    }
    public IEnumerable<customer> FindAll()
    {
        return dbContext.Customers.ToList();
    }
    public Customer FindById(int id)
    {
        return dbContext.Customers.Find(id);
    }
}

public interface IService<t>
{
    int Create(T t);
    IEnumerable<t> FindAll();
    T FindById(int id);	
    void SendMail();
    void CalculateTotalProfit();
}

public class CustomerService : IService<customer>
{
    private readonly IRepository<customer> _iCustomerRepository;
    public CustomerService(IRepository<customer> customerRepository)
    {
        _iCustomerRepository = customerRepository;
    }
    public int Create(Customer customer)
    {
        return _iCustomerRepository.Create(customer);
    }
    public IEnumerable<customer> FindAll()
    {
        return _iCustomerRepository.FindAll();
    }
    public Customer FindById(int id)
    {
        return _iCustomerRepository.FindById(id);
    }
    public void SendMail()
    { 
    //implement here..
    }
    public void void CalculateTotalProfit()
    {
    //implement here..
    }
}

public class CustomerController : Controller
{
    private readonly IService<customer> _customerService = null;
    public CustomerController(IService<customer> customerService)
    {
        _customerService = customerService;
    }
    public ActionResult Index()
    {
        var customers = _customerService.FindAll();
       return View(customers);
    }
    public ActionResult Create()
    {           
        return View();
    }
    [HttpPost]
    public ActionResult Create(Customer customer)
    {
        _customerService.Create(customer);
        return RedirectToAction("Index"); 
    }
}</t></t>

Here, we introduce two interfaces, IRepository and IService, to represent the abstraction and to ensure that the CustomerContrller class only calls methods or properties from the IService interface because the CustomerController class has a dependency on the Service class, and the Customer class calls method or properties from the IRepository interface because the Customer class has dependency on the Repository class. 

To write loosely couple code we can apply any of these injections, what injection to be applied will depend on the scenario. 

Now we will see how to integrate and implement Autofac with ASP.NET MVC4

Autofac is an IoC container that provides better integration for the ASP.NET MVC Framework, and manages dependencies between classes so that applications stay easy to change. We can easily integrate Autofac in our application; for that, first of all, we have to grab the NuGet packages. If you're not into NuGet, you can download Autofac from this site.  

Register components with Autofac: Firstly we have to add Autofac assemblies (Autofac.dll, Autofac.Configuration.dll, and Autofac.Integration.Mvc.dll) to our project. Then we write the following code block in Application_Start() of Global.asax.cs that will configure Autofac with ASP.NET MVC 4.

C#
var builder = new ContainerBuilder(); 
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType(typeof(CustomerService)).AsImplementedInterfaces();
builder.RegisterType(typeof(CustomerRepository)).AsImplementedInterfaces();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

Credits: Thanks to Rubayat Asirul Bari for reviewing this article and providing many helpful suggestions. 

Conclusion

Hopefully, you’ll be able to use this for your applications and it will make it a little bit easier to apply Dependency Injection Design Pattern in your application.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)