Подтвердить что ты не робот

Создайте две карты Automapper между теми же двумя типами объектов

Я использую AutoMapper в службе WCF для возврата объектов User. User имеет такие свойства, как AccountTeams, который сам имеет дочерние объекты. Все классы имеют карты AutoMapper.

В зависимости от вызываемого WCF OperationContract, я хочу вернуть разные объемы данных. Я хочу, чтобы один OperationContract возвращал объект User без его свойства AccountTeams (и их дочерних элементов) и другого OperationContract, чтобы вернуть User всю заполненную цепочку свойств.

Есть ли способ иметь две разные карты между одними и теми же двумя объектами или мне нужно выполнить полное сопоставление и null из свойств, которые я не хочу возвращать из службы?

4b9b3361

Ответ 1

Кевин Калитовски поднял хороший аргумент в отношении ответа wal: если нам нужны две конфигурации для обработки, которые должны быть разными, тогда нам не нужно дублировать все другие сопоставления, которые являются общими?

Я думаю, что нашел способ обойти это с помощью профилей: иметь один профиль для каждого из уникальных сопоставлений и третий профиль для общих сопоставлений. Затем создайте две конфигурации, по одному для каждого уникального профиля, а также добавьте общий профиль в каждую конфигурацию.

Пример, в 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

Я предполагаю, что вы выполняете сопоставление от 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, так и на configuration2 после вызовов CreateMap.

Update

Для Automapper 4.x используйте следующее:

var configuration1 = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<User, User>();
});

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

var configuration2 = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<User, User>().ForMember(dest => dest.Age, opt => opt.Ignore());
});

var mapper2 = configuration2.CreateMapper();
var mappedUser2 = mapper2.Map<User, User>(user);   //maps only Name

Ответ 3

Я думаю, что вы можете решить эту проблему с помощью различных объектов Configuration, как описано здесь, вы можете найти пример этого здесь