How to use Autofac for Dependency Injection in ASP.NET MVC

By FoxLearn 5/22/2024 2:51:27 AM   240
Using Autofac for Dependency Injection in ASP.NET MVC

Autofac is a popular dependency injection container for .NET applications, it's an IoC container for Microsoft .NET. It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity.

How to use Autofac for Dependency Injection in ASP.NET MVC

Here's a step-by-step guide on how to set up Autofac for dependency injection in ASP.NET MVC:

Open your Visual Studio, then create a new ASP.NET MVC project.

Next, Open the Manage Nuget Packages and install Autofac library

You can also install autofac via NuGet Package Manager or Package Manager Console:

Install-Package Autofac.Mvc5

I will create a simple sample allows you access to your database

public class Invoice
{
    public Guid Id { get; set; }
    public string InvoiceId { get; set; }
    public string BuyerId { get; set; }
    public string BuyerName { get; set; }
    public string BuyerAddress { get; set; }
    public string BuyerTaxId { get; set; }
    public decimal Total { get; set; }
    public string Note { get; set; }
    public string PaymentMethod { get; set; }
    public DateTime InvoiceDate { get; set; }
    public List<InvoiceDetails> InvoiceDetails { get; set; }
}
public class InvoiceDetails
{
    public Guid InvoiceId { get; set; }
    public string ItemId { get; set; }
    public string ItemName { get; set; }
    public string Unit { get; set; }
    public int Quantity { get; set; }
    public decimal Price { get; set; }
    public decimal Total => (Quantity * Price + Quantity * Price * Vat);
}

Next, We will create a simple interface to interact with your database

public interface IInvoiceService
{
    Guid Create(Invoice obj);
    Invoice GetInvoiceById(Guid id);
}

Let's implement the interface

public class InvoiceRepository : IInvoiceService
{
    public Guid Create(Invoice obj)
    {
        //Add code to store invoice to your database
        return new Guid();
    }

    public Invoice GetInvoiceById(Guid id)
    {
        //Add code to get invoice from your database
        return new Invoice();
    }
}

Create a DataModule class, then override Load method to register your class what you want to inject.

As you see we will use IInvoiceService interface to access our data from database, when we access a method it will be called the method from InvoiceRepository. You can create more repositories then implement IInvoiceService

public class DataModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<InvoiceRepository>().As<IInvoiceService>().InstancePerDependency();
        base.Load(builder);
    }
}

Create a WebModule class, then override Load method to register all controllers

public class WebModule : Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {
        if (builder == null)
            throw new ArgumentNullException(nameof(builder), "Argument builder can not be null.");
        //The line below tells autofac, when a controller is initialized, pass into its constructor, the implementations of the required interfaces
        builder.RegisterControllers(Assembly.GetExecutingAssembly());
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
        base.Load(builder);
    }
}

Create an AppConfig class to initialize your modules

public class AppConfig
{
    public static void Register()
    {
        // Create the container builder
        var builder = new ContainerBuilder();
        // Register your controllers with Autofac
        builder.RegisterModule(new DataModule());
        builder.RegisterModule(new WebModule());
        // Build the container
        IContainer container = builder.Build();
        // Set the dependency resolver for MVC
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    }
}

Use the builder.RegisterModule<T>() method to register your dependencies with Autofac. You can specify the interfaces they implement using .As<IInterface>().

In your ASP.NET MVC application, typically in the Global.asax.cs file, configure Autofac to handle dependency injection. Add the following code in the Application_Start method:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AppConfig.Register();
}

Once your dependencies are registered, you can inject them into your controllers. Here's an example:

You can create a ApiController or Controller, then add your code as shown below

public class InvoiceController : ApiController
{
    private readonly IInvoiceService _repository;

    // Constructor injection
    public InvoiceController(IInvoiceService repository)
    {
        _repository = repository;
    }

    [HttpPost]
    public IHttpActionResult Create([FromBody]Invoice model)
    {
        try
        {
            return Json(new { result = _repository.Create(model) });
        }
        catch (Exception ex)
        {
            return Json(new { result = ex.Message });
        }
    }

    [HttpGet]
    public IHttpActionResult GetInvoiceById(Guid id)
    {
        try
        {
            return Json(new { result = _repository.GetInvoiceById(id) });
        }
        catch (Exception ex)
        {
            return Json(new { result = ex.Message });
        }
    }
}

or

public class HomeController : Controller
{
    private readonly IInvoiceService _repository;

    public HomeController(IInvoiceService repository)
    {
        _repository = repository;
    }

    public ActionResult Index(Guid id)
    {
        return View(_repository.GetInvoiceById(id));
    }
}

I hope the sample above can help you solve the problem

Autofac will automatically resolve dependencies for your controllers based on the registered mappings.

Ensure that you dispose of the Autofac container when the application shuts down. You can do this in the Application_End method in Global.asax.cs:

protected void Application_End()
{
    var container = DependencyResolver.Current.GetService<IContainer>();
    container.Dispose();
}