首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >AutoMapper AutoMapperMappingException

AutoMapper AutoMapperMappingException
EN

Stack Overflow用户
提问于 2016-08-16 08:18:46
回答 1查看 1.3K关注 0票数 1

我发现了AutoMapper的一些非常奇怪的行为。这个简单的代码

代码语言:javascript
运行
复制
internal class Program
{
    private static void Main(string[] args)
    {
        Mapper.Initialize(cfg => { cfg.CreateMap<MyClass1, MyClass2>(); });
        Mapper.Initialize(cfg => { cfg.CreateMap<MyClass3, MyClass4>(); });

        var dto = new MyClass1();
        Mapper.Map<MyClass1, MyClass2>(dto);
    }
}

public class MyClass1
{
}

public class MyClass2
{
}

public class MyClass3
{
}

public class MyClass4
{
}

生成异常:

缺少类型映射配置或不支持映射。 映射类型: MyClass1 -> MyClass2 ConsoleApplication2.MyClass 1 -> ConsoleApplication2.MyClass 2

但是,如果更改两个初始化行的顺序,如下所示

代码语言:javascript
运行
复制
Mapper.Initialize(cfg => { cfg.CreateMap<MyClass3, MyClass4>(); });
Mapper.Initialize(cfg => { cfg.CreateMap<MyClass1, MyClass2>(); });

百事大吉。怎么了?到底怎么回事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-16 08:27:15

长话短说,吉米暂时放弃了AutoMapper中的静态内容,转而支持基于实例的映射。然而,正如Jimmy评论的那样:

静态映射器没有被删除,只是在代码中的任何地方调用CreateMap的能力。

问题的答案是,你试图初始化两次,而不是一次。

要回答关于如何将不同配置分散在代码中的下一个问题,可以使用Profile

若要回答如何配置所有这些内容,请参见以下内容:

对于AutoMapper 5.1.1

有一个MapperConfigurationExpression

https://github.com/AutoMapper/AutoMapper/blob/master/src/AutoMapper/Configuration/MapperConfigurationExpression.cs

您可以传递给映射程序,或者Mapper接受一个Action<IMapperConfigurationExpression>

IMapperConfigurationExpression公开了以下内容:

代码语言:javascript
运行
复制
void AddProfile(Profile profile)

因此,您几乎可以这样做,但在IMapper接口上注册所有内容,这似乎是4.2.1的目标。

对于AutoMapper 4.2.1 (简要介绍概要文件)

下面是一个示例配置文件:

代码语言:javascript
运行
复制
using AutoMapper;

using TreasuryRecords.Database.Models;
using TreasuryRecords.Requests.Account.Models;

public class AccountMappings : Profile
{
    protected override void Configure()
    {
        this.CreateMap<RegisterDto, Client>()
            .ForMember(x => x.UserName, c => c.MapFrom(x => x.Email));
    }
}

下面是我如何注册我的个人资料的一个例子:

代码语言:javascript
运行
复制
using System;
using System.Linq;
using System.Reflection;

using AutoMapper;

using TreasuryRecords.Requests.Authenticate.Login;

public static class AutoMapperConfig
{
    public static void Configure()
    {
        Assembly
            .GetExecutingAssembly()
            .RegisterConfigurations();

        typeof(LoginRequest)
            .Assembly
            .RegisterConfigurations();
    }

    public static void RegisterConfigurations(this Assembly assembly)
    {
        var types = assembly.GetTypes();

        var automapperProfiles = types
                                    .Where(x => typeof(Profile).IsAssignableFrom(x))
                                    .Select(Activator.CreateInstance)
                                    .OfType<Profile>()
                                    .ToList();

        // so here you can pass in the instance of mapper
        // I just use the static for ease
        automapperProfiles.ForEach(Mapper.Configuration.AddProfile);
    }
}

我是这样将它添加到DI中的:

代码语言:javascript
运行
复制
public static void RegisterAutoMapper(this IUnityContainer container)
{
    container.RegisterType<IMapper>(new InjectionFactory(_ => Mapper.Instance));
}

我在这里使用的是统一,但是非常简单,只需在接口Mapper.Instance中注册IMapper即可。

然后注入IMapper并按如下方式使用:

代码语言:javascript
运行
复制
this.mapper.Map<Client>(message.RegistrationDetails);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38969845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档