每个程序集调用一次 AddAutoMapper 而不是传入多个程序集?

Que*_*n3r 7 c# automapper

我有一个带有 Web API 项目和库项目的多层项目。这两个项目都依赖于 AutoMapper(以及 Microsoft.Extensions.DependencyInjection 的 AutoMapper 扩展)。基于此

https://docs.automapper.org/en/latest/Dependency-injection.html#asp-net-core

在启动文件中,我正在为所有图层设置 AutoMapper

Assembly apiAssembly = Assembly.GetExecutingAssembly();
Assembly myLibraryAssembly = Assembly.Load("MyLibrary");

services.AddAutoMapper(apiAssembly, myLibraryAssembly);
Run Code Online (Sandbox Code Playgroud)

正如您在此处看到的,API 项目需要通过名称加载它们来了解所有引用的库项目。我更喜欢每个项目都能够自行注册的方式。基于此示例代码

https://github.com/jasontaylordev/CleanArchitecture/blob/master/src/Application/DependencyInjection.cs

我在我的库项目中创建了这样一个文件

public static class DependencyInjection
{
    public static IServiceCollection AddMyLibrary(this IServiceCollection services)
    {
        Assembly executingAssembly = Assembly.GetExecutingAssembly(); // MyLibrary assembly

        services.AddAutoMapper(executingAssembly);
        // ... setup other services

        return services;
    }
}
Run Code Online (Sandbox Code Playgroud)

在 API 项目中,我现在可以做到这一点

Assembly executingAssembly = Assembly.GetExecutingAssembly();

services.AddAutoMapper(executingAssembly);
services.AddMyLibrary();
Run Code Online (Sandbox Code Playgroud)

该代码似乎工作正常,但AddAutoMapper会被调用两次。一次用于 API 程序集,一次用于库程序集。我应该坚持第一种方法,因为 AutoMapper 应该只添加一次还是可以将其分开?

Chr*_*.ZA 8

接受的答案当时是正确的,但最近情况似乎发生了变化。

AutoMapper.Extensions.Microsoft.DependencyInjection 包已更新以允许多次调用 AddAutoMapper()。

有关详细信息,请参阅 PR使用 Microsoft.Extensions.Options 配置 AutoMapper。您需要将软件包更新到8.0.0或更高版本才能使用它。


Iva*_*oev 5

该代码似乎工作正常,但AddAutoMapper会被调用两次。一次用于 API 程序集,一次用于库程序集。我应该坚持第一种方法,因为 AutoMapper 应该只添加一次还是可以将其分开?

您应该坚持第一种方法,因为AddAutoMappper在第二次、第三次等时间调用时什么也不做,因此传递给这些调用的程序集中的配置文件和其他 AM 相关类型将不会被注册。

在所有公共重载调用的私有方法的实现开头可以看出AddAutoMapper

private static IServiceCollection AddAutoMapperClasses(IServiceCollection services, Action<IServiceProvider, IMapperConfigurationExpression> configAction, 
    IEnumerable<Assembly> assembliesToScan, ServiceLifetime serviceLifetime = ServiceLifetime.Transient)
{
    // Just return if we've already added AutoMapper to avoid double-registration
    if (services.Any(sd => sd.ServiceType == typeof(IMapper)))
        return services;
Run Code Online (Sandbox Code Playgroud)

后跟实际的注册码,最后注册IMapper.

目前有一个悬而未决的问题允许使用选项模式来配置 AutoMapper #132与您的问题完全相同。