38

我第一次使用自动映射。

我正在开发 c# 应用程序,我想使用自动映射器。

(我只是想知道如何使用它,所以我没有asp.net应用程序和MVC应用程序。)

我有三个类库项目。

在此处输入图像描述

我想在服务项目中编写传输过程。

所以我想知道我应该如何以及在哪里配置 Auto Mapper ?

4

6 回答 6

60

因此,根据 Bruno 的回答和John Skeet 关于单例的帖子,我想出了以下解决方案,使其仅运行一次并在类库中完全隔离,这与接受的答案不同,后者依赖于库的使用者来配置映射父项目:

public static class Mapping
{
    private static readonly Lazy<IMapper> Lazy = new Lazy<IMapper>(() =>
    {
        var config = new MapperConfiguration(cfg => {
            // This line ensures that internal properties are also mapped over.
            cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;
            cfg.AddProfile<MappingProfile>();
        });
        var mapper = config.CreateMapper();
        return mapper;
    });

    public static IMapper Mapper => Lazy.Value;
}

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<Source, Destination>();
        // Additional mappings here...
    }
}

然后在您需要将一个对象映射到另一个对象的代码中,您可以执行以下操作:

var destination = Mapping.Mapper.Map<Destination>(yourSourceInstance);

注意:此代码基于 AutoMapper 6.2,可能需要对旧版本的 AutoMapper 进行一些调整。

于 2018-03-23T19:06:27.357 回答
28

您可以将配置放置在任何位置:

public class AutoMapperConfiguration
{
    public static void Configure()
    {
        Mapper.Initialize(x =>
            {
                x.AddProfile<MyMappings>();              
            });
    }
}

 public class MyMappings : Profile
{
    public override string ProfileName
    {
        get { return "MyMappings"; }
    }

    protected override void Configure()
    {
    ......
    }

但它必须由应用程序在某些时候使用库调用:

void Application_Start()
    {               
        AutoMapperConfiguration.Configure();
    }
于 2014-10-20T12:05:00.777 回答
8

您的库之外的任何人都不必配置 AutoMapper

我建议您使用基于实例的方法,使用IMapper. 这样一来,您的库之外的任何人都不必调用任何配置方法。MapperConfiguration您可以在类库中定义一个并从那里创建映射器。

var config = new MapperConfiguration(cfg => {
    cfg.AddProfile<AppProfile>();
    cfg.CreateMap<Source, Dest>();
});

IMapper mapper = config.CreateMapper();
// or
IMapper mapper = new Mapper(config);
var dest = mapper.Map<Source, Dest>(new Source());
于 2017-12-16T23:28:02.013 回答
3

马尔科的回答是正确的。

我们也可以通过以下简单的解决方案。

 public static class ObjectMapper
{
    public static IMapper Mapper
    {
        get
        {
            return AutoMapper.Mapper.Instance;
        }
    }
    static ObjectMapper()
    {
        CreateMap();
    }
    private static void CreateMap()
    {
        AutoMapper.Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<SourceClass, DestinationClass>();
        });
    }
}
我们可以像这样使用它。
public class SourceClass
{
    public string Name { get; set; }
}
public class DestinationClass
{
    public string Name { get; set; }
}
SourceClass c1 = new SourceClass() { Name = "Mr.Ram" };

DestinationClass c2 = ObjectMapper.Mapper.Map<DestinationClass>(c1);
于 2019-03-11T11:51:07.630 回答
0

我也遇到过这种需求。我在 .Net 6.0 中所做的是,我创建了一个库项目并创建了配置文件类:

public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Entity, Dto>();
        CreateMap<Dto, Entity>();
        ......
    }
}

在 api 或 web 项目中,我只是创建一个子类来继承上面的配置文件,并将其注册到 startup.cs services.AddAutoMapper(typeof(Startup));。

于 2021-07-07T13:20:22.797 回答
0

我使用了 Patel Vishal 的解决方案,并根据我的需要对其进行了定制。它是一个通用类,可确保每个对象映射仅将一个映射实例保存在内存中。

  1. TModel - 是一个 DTO 对象
  2. TData - 是实体框架中的数据库表对象
  3. DTO.IBaseModel - 是 DTO 对象的基类,具有一个属性:ID
  4. IBaseModel - 是实体框架数据库实体的基类,仅具有 ID 属性

public static class ObjectMapper<TModel, TData>
    where TModel : class, DTO.IBaseModel, new() 
    where TData : class, IBaseModel, new()
{
    private static readonly MapperConfiguration _mapperConfiguration;
    public static IMapper Mapper => new Mapper(_mapperConfiguration);

    static ObjectMapper()
    {
        _mapperConfiguration ??= CreateMap();
    }

    private static MapperConfiguration CreateMap()
    {
        return new (cfg =>
        {
            cfg.CreateMap<TData, TModel>();
        });
    }
}

我在 BaseService<TData, TModel> (服务/存储库模式)中使用此类:

    public virtual TModel Convert(TData t)
    {
        return ObjectMapper<TModel, TData>.Mapper.Map<TModel>(t);
    }

如您所见,它是一种虚拟方法。如果继承服务需要自定义,则可以覆盖映射。

于 2021-03-14T17:03:15.333 回答