尝试将AutoMapper添加到Asp.net Core 2?

71

我之前参与了一个asp.net core 1.1的项目,使用了AutoMapper。

在asp.net core 1.1中,我在启动文件中添加了services.AddAutoMapper()

asp.net core 1.1中的启动文件:

    public void ConfigureServices(IServiceCollection services)
    {
        //Some Code

        services.AddMvc();
        services.AddAutoMapper();
    }

我可以轻松地在Controller中使用AutoMapper。

Controller :

 public async Task<IActionResult> AddEditBook(AddEditBookViewModel model)
 {
    Book bookmodel = AutoMapper.Mapper.Map<AddEditBookViewModel, Book>(model);
    context.books.Add(bookmodel);
    context.SaveChanges();
 }

一切都很好。

但是我目前正在开发一个Asp.net Core 2项目,启动文件中的services.AddAutoMapper()出现错误。

Error CS0121 The call is ambiguous between the following methods or properties: 'ServiceCollectionExtensions.AddAutoMapper(IServiceCollection, params Assembly[])' and 'ServiceCollectionExtensions.AddAutoMapper(IServiceCollection, params Type[])'

这个错误的原因是什么?
此外,在asp.net core 2中,services.AddAutoMapper有一些参数。我应该向这个参数传送什么内容?


不要混合使用 .NET Core 的版本。您可能引用了一些 .NET Core 或 ASP.NET Core 1.1 组件的引用。您必须将它们全部更新到相同的版本(即 2.0 或 2.1-rc),否则您仍然在引用过时的 Automapper 版本。 - Tseng
12个回答

174

如果您正在使用AspNet Core 2.2和AutoMapper.Extensions.Microsoft.DependencyInjection v6.1,您需要在启动文件中使用以下内容:

services.AddAutoMapper(typeof(Startup));

12
FYI给下一个遇到类似问题的人:我必须安装Microsoft.Extensions.DependencyInjection.Abstractions才能使services.AddAutoMapper(typeof(Startup))正常工作。 - Marius
3
在 .NET Core 2.2 中,这个改动让我解决了构建错误,但在运行时因缺少映射配置而失败。对我有效的方法是在语句中列出所有的配置文件类,即: services.AddAutoMapper(typeof(profileClassName1),typeof(profileClassName2)); - nir weiner
2
@nirweiner的评论是正确的,但你只需要指向一个配置文件类之一,因为它要求在程序集中搜索。如果你的配置文件在同一个程序集中,dev-siberia的答案是有效的。 - CularBytes

43
您可能已经更新了ASP.NET Core的依赖项,但仍在使用过时的AutoMapper.Extensions.Microsoft.DependencyInjection软件包。
对于ASP.NET Core,您需要至少版本3.0.1,可以从https://www.nuget.org/packages/AutoMapper.Extensions.Microsoft.DependencyInjection/3.0.1获取该版本。该版本引用了AutoMapper 6.1.1或更高版本。

AutoMapper (>= 6.1.1)

Microsoft.Extensions.DependencyInjection.Abstractions (>= 2.0.0)

Microsoft.Extensions.DependencyModel (>= 2.0.0)

旧版本的软件包依赖于Microsoft.Extensions.DependencyInjection.Abstractions1.1.0,因为Microsoft.Extensions.DependencyInjection.Abstractions1.1.0和2.0之间存在重大变化,所以无法与ASP.NET Core一起使用。

3
谢谢。我更新了AutoMapper.Extensions.Microsoft.DependencyInjection,错误得到了解决。 - topcool
1
在控制台中执行以下命令:dotnet add package AutoMapper.Extensions.Microsoft.DependencyInjection --version 8.0.1 - Developer Marius Žilėnas
针对dotnet 5.0,AutoMapper.Extensions.Microsoft.DependencyInjection 8.1.1似乎无法正常工作。 - Smile4ever

16

在新的版本(6.1)的AutoMapper.Extensions.Microsoft.DependencyInjection nuget包中,您应该按照以下方式使用它:

services.AddAutoMapper(Type assemblyTypeToSearch);
// OR
services.AddAutoMapper(params Type[] assemblyTypesToSearch);

e.g:

services.AddAutoMapper(typeOf(yourClass)); 

你说的assemblyType是什么意思?我有很多个配置文件,所以不能一个一个地添加。抱歉,我在C#方面还是新手。谢谢! - sshanzel
类似于 services.AddAutoMapper(typeOf(yourClass)); 的代码。 - Mohammad Dayyan
是的,我指的是那些答案在上面提到过,它们确实起作用,但我只是想知道 assemblyType 的解释是什么。很抱歉,我真的很菜。 - sshanzel
我的意思是一个程序集中可以有一个或多个类型。如果你想知道什么是程序集,可以参考这个链接:https://dev59.com/E3M_5IYBdhLWcg3wfTE0 - Mohammad Dayyan

10

9

这些方法对我都没有用,我有一个.NET Core 2.2项目,配置映射器的完整代码如下(在ConfigureService()方法中的一部分):

    // Auto Mapper Configurations
    var mappingConfig = new MapperConfiguration(mc =>
    {
        mc.AddProfile(new SimpleMappings());
    });

    IMapper mapper = mappingConfig.CreateMapper();
    services.AddSingleton(mapper);

然后我有一个Mappings类,我将其放置在BL项目中:

public class SimpleMappings : Profile
    {
        public SimpleMappings()
        {
            CreateMap<DwUser, DwUserDto>();
            CreateMap<DwOrganization, DwOrganizationDto>();
        }
    }

最后,使用映射器的方式如下:

public class DwUserService : IDwUserService
    {
        private readonly IDwUserRepository _dwUserRepository;
        private readonly IMapper _mapper;

        public DwUserService(IDwUserRepository dwUserRepository, IMapper mapper)
        {
            _dwUserRepository = dwUserRepository;
            _mapper = mapper;
        }

        public async Task<DwUserDto> GetByUsernameAndOrgAsync(string username, string org)
        {
            var dwUser = await _dwUserRepository.GetByUsernameAndOrgAsync(username, org).ConfigureAwait(false);
            var dwUserDto = _mapper.Map<DwUserDto>(dwUser);

            return dwUserDto;
        }
}

这里是一个关于同一主题的类似链接: 如何在ASP.NET Core中设置Automapper


1
非常感谢您发布这个完整的示例! - SWalters
1
这是唯一一个对我有效的示例。谢谢! - Jemes

9
如果您正在使用AspNet Core 2.2,请尝试更改您的代码。
从:
services.AddAutoMapper();

致:

services.AddAutoMapper(typeof(Startup));

它对我起作用了。


6
在 .Net 6 中,您可以这样做
builder.Services.AddAutoMapper(typeof(Program).Assembly); // Since there is no Startup file

builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

基本上,需要按照下面屏幕截图中显示的程序集名称。 enter image description here

4

我通过创建一个继承了 AutoMapper.Profile 的类来解决这个问题。

    public class model_to_resource_profile : Profile
    {
        public model_to_resource_profile()
        {
            CreateMap<your_model_class, your_model_resource_class>();
        }
    }

Startup.cs 中添加以下代码:

services.AddAutoMapper(typeof(model_to_resource_profile ));

3
尝试这个,适用于2.1版本及以上,我没有使用任何早期版本,因此无法确定。 services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

1
这个答案对我很有帮助,当我在我的解决方案中为额外的项目进行AutoMapper时。谢谢你。 - Fadhly Permata

1
如果您在添加自动映射器时遇到问题,最好检查您添加的类型和版本。如果不是“AutoMapper.Extensions.Microsoft.DependencyInjection”,那么您将无法使用“services.AddAutoMapper()”。有时,您可能会错误地添加“AutoMapper”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接