如何在类库项目中配置Auto mapper?

时间:2014-10-20 04:48:33

标签: c# automapper automapper-2 automapper-3

我第一次使用自动映射。

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

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

我有三个类库项目。

enter image description here

我想在服务项目中编写转移过程。

所以我想知道如何以及在哪里配置自动映射器?

5 个答案:

答案 0 :(得分:24)

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

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();
    }

答案 1 :(得分:19)

所以基于Bruno的答案和John Skeet's post about singletons我提出了以下解决方案,只运行一次并在类库中完全隔离,这与接受的答案不同,后者依赖于库的使用者来配置父项目中的映射:

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进行一些调整。

答案 2 :(得分:4)

您图书馆外的任何人都不得配置AutoMapper

我建议您使用instance based approach using an 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());

答案 3 :(得分: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(服务/存储库模式)中使用这个类:

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

如你所见,它是一个虚方法。如果继承服务需要定制,可以覆盖映射。

答案 4 :(得分:0)

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

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

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