在相同的两个对象类型之间创建两个Automapper映射

时间:2013-01-10 19:51:21

标签: c# .net wcf automapper

我在WCF服务中使用AutoMapper来返回User个对象。 User具有AccountTeams等属性,其本身具有子对象。所有类都有AutoMapper贴图。

根据调用的WCF OperationContract,我想返回不同数量的数据。我希望一个OperationContract返回User对象,而不填充AccountTeams属性(及其子代),另一个OperationContract返回整个链User填写的属性。

有没有办法在同一个两个对象之间有两个不同的地图,还是我需要执行完整的映射,并null输出我不想从服务中返回的属性?

3 个答案:

答案 0 :(得分:15)

我假设您要从User映射到User(如果不是,则只需更改目标类型)

为以下示例假设此类:

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}

然后,您可以使用单独的AutoMapper.Configuration来定义2个地图:

[TestMethod]
public void TestMethod()
{
    var configuration1 = new Configuration(new TypeMapFactory(), MapperRegistry.AllMappers());
    var mapper1 = new MappingEngine(configuration1);
    configuration1.CreateMap<User, User>();

    var user = new User() { Name = "John", Age = 42 };
    var mappedUser1 = mapper1.Map<User, User>(user);//maps both Name and Age

    var configuration2 = new Configuration(new TypeMapFactory(), MapperRegistry.AllMappers());
    configuration2.CreateMap<User, User>().ForMember(dest => dest.Age, opt => opt.Ignore());
    var mapper2 = new MappingEngine(configuration2);

    var mappedUser2 = mapper2.Map<User, User>(user);
    Assert.AreEqual(0, mappedUser2.Age);//maps only Name
}

为了避免每隔两次其他类型的映射,您可以添加一个公共方法,该方法需要Configuration映射User可以访问的所有内容,并在configuration1和{{{{}}上调用此方法1}}调用configuration2之后。

更新

对于Automapper 4.x,请使用以下命令:

CreateMap

答案 1 :(得分:12)

Kevin Kalitowski对沃尔玛的回答提出了一个很好的观点:如果我们需要两种配置来处理需要不同的映射,那么我们不必复制所有其他常见的映射?

我认为我已经找到了解决此问题的方法:使用每个唯一映射的一个配置文件和公共映射的第三个配置文件。然后创建两个配置,每个配置对应一个唯一的配置文件,同时也将公共配置文件添加到每个配置中。

示例,在AutoMapper 4.2中:

要映射的类:用户和车辆:

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class Vehicle
{
    public int FleetNumber { get; set; }
    public string Registration { get; set; }
}

个人资料:

public class Profile1 : Profile
{
    protected override void Configure()
    {
        base.CreateMap<User, User>();
    }
}

public class Profile2 : Profile
{
    protected override void Configure()
    {
        base.CreateMap<User, User>().ForMember(dest => dest.Age, opt => opt.Ignore());
    }
}

public class CommonProfile : Profile
{
    protected override void Configure()
    {
        base.CreateMap<Vehicle, Vehicle>();
    }
}

然后创建配置并映射对象:

[TestMethod]
public void TestMethod()
{
    var user = new User() { Name = "John", Age = 42 };
    var vehicle = new Vehicle {FleetNumber = 36, Registration = "XYZ123"};

    var configuration1 = new MapperConfiguration(cfg =>
    {
        cfg.AddProfile<CommonProfile>();
        cfg.AddProfile<Profile1>();
    });

    var mapper1 = configuration1.CreateMapper();
    var mappedUser1 = mapper1.Map<User, User>(user);//maps both Name and Age
    var mappedVehicle1 = mapper1.Map<Vehicle, Vehicle>(vehicle);//Maps both FleetNumber 
                                                                //and Registration.

    var configuration2 = new MapperConfiguration(cfg =>
    {
        cfg.AddProfile<CommonProfile>();
        cfg.AddProfile<Profile2>();
    });

    var mapper2 = configuration2.CreateMapper();
    var mappedUser2 = mapper2.Map<User, User>(user);//maps only Name
    var mappedVehicle2 = mapper2.Map<Vehicle, Vehicle>(vehicle);//Same as mappedVehicle1.
}

我尝试了这个并且它有效。

答案 2 :(得分:1)

我认为您可以使用here所述的不同配置对象解决此问题,您可以找到此here的示例