.net Core Automapper Dependency Injection from child libraries

The Problem

I have recently built a set of .net core libraries that leverage automapper to help transform between my database entities and my contracts/models that are used to provide separation between the Data Access Layer and the Views.

I them needed to register this libraries AutoMapper configuration into the dependency chain.

The child library implemented its own dependency registration via an IServiceCollection extension class like so;

public static void AddDependenciesMyLibrary(this IServiceCollection services) 
{
	// register automapper
    services.AddAutoMapper(Assembly.GetAssembly(typeof(MyAutoMapperLibraryProfie)));
	
    // add registration of DI libraries
    ...
}

Where we register the assembly that contains an AutoMapper : Profile extended class, as documented (sparsely) here;

ASPNET.Core DI Regsistration

In the asp .net core website that consumed this library it would also implement its own IServiceCollection extension calling;

    
    services.AddDependenciesMyLibrary();
    services.AddAutoMapper(Assembly.GetAssembly(typeof(WebAppAutoMapperProfile)));
    

The Issue

This would not work as the code would keep crashing with issues with the automapper not having the mapped profiles.

The reason why?

After much trial and error and reading all of the internet like this one:
Please add support for calling AddAutoMapper() multiple times
it appears that there is a rule you must know

you can only call AddAutoMapper() once in services collection

and the first call is the one that will be retained, all subsequent calls are ignored.

The Solution

So I resolved this by adjusting the IServiceCollection Extension class as follows:

public static void AddDependenciesMyLibrary(this IServiceCollection services, IList assemblies) 
{
	// add automapper
    assemblies.Add(Assembly.GetAssembly(typeof(MyAutoMapperLibraryProfie)));
	
    // add registration of DI libraries
    ...
}

What this now does is traverse the Dependency chain down through my class library hierarchy and each library can maintain its own set of know assemblies, building up the collection of assemblies, but NOT calling AddAutoMapper().

The client application that consumes these libraries would do the following;

	// new up the assembly list
	var assemblies = new List(); 
	// register DI and add to the assemblies collection
	services.AddDependenciesMyLibrary(assemblies); 
	// add the apps local automapper config 
	assemblies.Add(Assembly.GetAssembly(typeof(Startup)));
	// Initialise AutoMapper
	services.AddAutoMapper(assemblies);

This means that by the time the code returns from the Services.AddDependciesXXX call the assemblies collection will be populated with the full list of assemblies that contain AutoMapper Profiles, it is then added to locally and registered into the DI framework.

This works and the client consuming the class library need not know anything about the internal workings of library to be able to register automapper.

Hope this registration pattern helps

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.