Autofac is a tool for managing dependencies between classes that simplifies application development as it grows in size and complexity. Asp.Net Core, unlike the classic Asp.Net, supports built-in Dependency Injection, but with Autofac, project development is easier and faster. For example, if we have an interface called IUserService and a class called UserService that implements this interface, we should manually introduce both this interface and class to DI, as follows:

services.AddScoped<IUserService, UserService>();

We have to do this for all the interfaces used, and when the size of the project grows, it takes a bit of time and most of the time we forget to register the interfaces. But with Autofac you do not need to do this and the operation of registering interfaces is done automatically. Implementing Autofac in Asp.Net Core 3 with other older versions of Net Net Core. Is different. 

You must first install the following packages through Nuget.

  • Autofac version 5.1.2
  • Autofac.Extensions.DependencyInjection version 6.0.0

Then the first change in the Program class should be changed as follows.

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseServiceProviderFactory(new AutofacServiceProviderFactory()) // <--NOTE THIS
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

In Net Core. We have three types of life time for registering

  1. Scoped
  2. Transient
  3. Singleton

Scoped : If a service is registered with this type of life time, one object of the desired class is created for each request .

Transient : If a service is registered with this type of life time, an object of the desired class is created for each service .

Singleton : If a service is registered with this type of live time, in the first step, it is checked whether there is an object of this class in the system or not. If it does not exist, an instance of the object is created and given to the DI. If the object is in the system, it returns the current object and prevents new objects from being created. This life time, as its name suggests, implements the Singleton pattern.

Here are three interfaces for markup only. By doing this, we specify how each service should be registered.

public interface IScopeDependency { }
public interface ISingletoneDependency { }
public interface ITransientDependency { }

Next, when creating classes, we must specify how this class should be registered. We do this by inheriting the above interfaces as follows:

public interface IUserService
{
    string DoSomething();
}
public class UserService : IUserService, IScopeDependency
{
    public string DoSomething()
    {
        return "Hi ;)";
    }
}

If we want to register the UserService class of Singleton type, we can inherit ISingletoneDependency instead of IScopeDependency. Next, using the ContainerBuilder, we specify that classes inherited from the IScopeDependency interface must be registered as InstancePerLifetimeScope (the same as the previous Scoped) and ...

Note:  Autofac specifies that the UserService class should be given in exchange for a request for an IUserService interface. This means that the class name must be exactly the same as the interface and not just the letter "I" .

 In this section, we have used a method extension to prevent the Startup class from becoming crowded and just call the method.

public static void AutofacConfig(this ContainerBuilder builder)
{
    var assembly = typeof(Startup).Assembly;
    builder.RegisterAssemblyTypes(assembly)
                    .AssignableTo<IScopeDependency>()
                    .AsImplementedInterfaces()
                    .InstancePerLifetimeScope();

    builder.RegisterAssemblyTypes(assembly)
                    .AssignableTo<ITransientDependency>()
                    .AsImplementedInterfaces()
                    .InstancePerDependency();

    builder.RegisterAssemblyTypes(assembly)
                    .AssignableTo<ISingletoneDependency>()
                    .AsImplementedInterfaces()
                    .SingleInstance();
}

If your project consists of several layers and each layer has its own dependency, you can send the assembly of other layers as a parameter to the RegisterAssemblyTypes method because the input of this method is of type params and you can pass multiple assemblies. Next we need to create a method called ConfigureContainer like the one below in the Startup class and configure it to run Autofac.

public void ConfigureContainer(ContainerBuilder containerBuilder)
{
    containerBuilder.AutofacConfig();
}

Finally, request IUserService through the User Controller Constructor

public class UserController : Controller
{
    private readonly IUserService _userService;

    public UserController(IUserService userService)
    {
        _userService = userService;
    }

    public IActionResult Index()
    {
        return Ok(_userService.DoSomething());
    }
}


Powered by Froala Editor

Comments