0

I have the following code that add automapper to my app.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    services.AddHttpClient();

    services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
}

The AppDomain.CurrentDomain.GetAssemblies() returns only assemblies that were loaded at the time it is called. I can see that some of my assemblies which contain my mappings have not been yet loaded and as a result mappings are not loaded which returns me errors about missing map types.

How do I get all assemblies referenced by my project?

theduck
  • 2,589
  • 13
  • 17
  • 23
pantonis
  • 5,601
  • 12
  • 58
  • 115
  • Why you need to pass the parameter services.AddAutoMapper method. You can directly call it like services.AddAutoMapper(). It is working fine for me. Moreover, have you created Automapper Profile classes that inherits from Profile? – Ankush Jain Sep 27 '19 at 07:19
  • Yes I have created profiles. AddAutoMapper() is marked as obsolete – pantonis Sep 27 '19 at 07:20
  • _“`AppDomain.CurrentDomain.GetAssemblies()` returns only assemblies that were loaded at the time it is called”_ – So it works by design. If you want other assemblies, then pass those assemblies directly. – poke Sep 27 '19 at 07:22
  • This is the exact reason why the no params overload is obsolete :) You can pass the assemblies explicitly, or write the code to load them yourself. – Lucian Bargaoanu Sep 27 '19 at 07:25
  • Which assembly is not load during application start? Is there any demo to reproduce your issue? – Edward Oct 04 '19 at 05:20

2 Answers2

0

Reference - From official AutoMapper docs

ASP.NET Core

There is a NuGet package to be used with the default injection mechanism described here and used in this project.

You define the configuration using profiles. And then you let AutoMapper know in what assemblies are those profiles defined by calling the IServiceCollection extension method AddAutoMapper at startup:

services.AddAutoMapper(profileAssembly1, profileAssembly2 /*, ...*/);

or marker types:

services.AddAutoMapper(typeof(ProfileTypeFromAssembly1), typeof(ProfileTypeFromAssembly2) /*, ...*/);

Now you can inject AutoMapper at runtime into your services/controllers:

public class EmployeesController {
    private readonly IMapper _mapper;

    public EmployeesController(IMapper mapper) => _mapper = mapper;

    // use _mapper.Map or _mapper.ProjectTo
}
Ankush Jain
  • 5,654
  • 4
  • 32
  • 57
  • I was looking for a way to avoid explicitly specifying the assemblies one by one. I suppose there is not any way to get all referenced assemblies so I have to explicitly set them – pantonis Sep 27 '19 at 07:47
  • Assemblies will be loaded into the App Domain once they are used first time. So, yes, you should explicitly specify the typeof(Profile) and that will eventually load the assembly. – Ankush Jain Sep 27 '19 at 07:52
  • As I already said in my initial post I know how to do this explicitly. What I am looking is to find a way to get referenced assemblies – pantonis Sep 27 '19 at 08:05
0

This worked fine for me using .NET 6, AutoMapper 10.1.1 and AutoMapper.Extensions.Microsoft.DependencyInjection 8.1.1

services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

However when upgrading to .NET 7, AutoMapper 11.0.1 and AutoMapper.Extensions.Microsoft.DependencyInjection 11.0.0 a Controller that had IMapper mapper injected simply started returning HTTP 500. It never even got to the constructor of the Controller.

I then switched my code to:

services.AddAutoMapper(typeof(MappingProfile).Assembly);

Then everything started working again. My point with this is that you need to check and show which version you are using and read the docs based on that version.

Ogglas
  • 62,132
  • 37
  • 328
  • 418