Register dependencies via reflection + Autofac module

register dependency

Imagine that you have ten or hundred class in your repository. And now you need to register each of them. Do you want to do it this way?

services.AddSingleton<ISomeSingetonInterface, SomeSingleton>();
services.AddScoped<ISomeInterfaceRepository, SomeRepository>();
services.AddScoped<ISomeInterfaceRepository2, SomeRepository2>();
services.AddScoped<ISomeInterfaceService, SomeService>();
services.AddScoped<ISomeInterfaceService2, SomeService2>();
services.AddScoped<ISomeInterfaceHandler, SomeHandler>();
services.AddScoped<ISomeInterfaceHandler2, SomeHandler2>();
......

Very tedious work, whenever you add some class you need to again register that dependency. Instead of that you can use reflection + Autofac module and automatically register all class that have “marker” interface.

Example

Create a marker to all your (e.g) repository interfaces.

public interface IRepository
{
}

Mark all interfaces belonging to the repositories with IRepository marker.

public interface ISomeInterfaceRepository : IRepository
{
    ....
}

Now you have all what is need to register all repository at once.

To make that I’ll use for it IoC container Autofac but it can be some other if you prefer.

So at first, let’s make module that will register all repositories via reflection.

This class will inherit after Autofac.Module and override function Load to register all dependencies on my current assembly which register all interfaces with the mark interface IRepository as a single instance.

public class RepositoryModule : Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {
        var assembly = typeof(RepositoryModule)
            .GetTypeInfo()
            .Assembly;

        builder.RegisterAssemblyTypes(assembly)
                .Where(x => x.IsAssignableTo<IRepository>())
                .AsImplementedInterfaces().SingleInstance();
    }
}

At this point I can analogously do for other modules, for example, services or handlers.

Then create a container to register all modules which you have.

public class ContainerModule : Module
{
    private readonly IConfiguration _configuration;

    public ContainerModule(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterModule<ServiceModule>();
        builder.RegisterModule<HandlerModule>();
        builder.RegisterModule<RepositoryModule>();
    }
}

And now you only need to modify the start-up class in order for the modules to register properly.

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    var builder = new ContainerBuilder();
    builder.Populate(services);
    builder.RegisterModule(new ContainerModule(Configuration));
    return new AutofacServiceProvider(ApplicationContainer);
}

That’s end, we can now enjoy that the containers automatically register the dependencies that are marked with appropriate markers.

Let’s Make Life Easier

 

Leave a Reply

Your email address will not be published. Required fields are marked *