2010-02-10 9 views

Odpowiedz

113

Zastosowanie ConstructUsing

ten pozwoli Ci określić, które konstruktor używać podczas mapowania. ale wtedy wszystkie inne właściwości będą automatycznie mapowane zgodnie z konwencjami.

Należy również zauważyć, że różni się on od ConvertUsing tym, że konwersja przy użyciu nie będzie kontynuowała mapowania za pośrednictwem konwencji, zamiast tego zapewni pełną kontrolę nad mapowaniem.

Mapper.CreateMap<ObjectFrom, ObjectTo>() 
    .ConstructUsing(x => new ObjectTo(arg0, arg1, etc)); 

...

using AutoMapper; 
using NUnit.Framework; 

namespace UnitTests 
{ 
    [TestFixture] 
    public class Tester 
    { 
     [Test] 
     public void Test_ConstructUsing() 
     { 
      Mapper.CreateMap<ObjectFrom, ObjectTo>() 
       .ConstructUsing(x => new ObjectTo(x.Name)); 

      var from = new ObjectFrom { Name = "Jon", Age = 25 }; 

      ObjectTo to = Mapper.Map<ObjectFrom, ObjectTo>(from); 

      Assert.That(to.Name, Is.EqualTo(from.Name)); 
      Assert.That(to.Age, Is.EqualTo(from.Age)); 
     } 
    } 

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

    public class ObjectTo 
    { 
     private readonly string _name; 

     public ObjectTo(string name) 
     { 
      _name = name; 
     } 

     public string Name 
     { 
      get { return _name; } 
     } 

     public int Age { get; set; } 
    } 
} 
+0

Zgaduję, że "ConstructUsing" musi być w nowszej wersji automappera niż w używamy. Dzięki Jon – jlembke

+6

Dziękuję za ten przykład Jon. "ConstructUsing" jest świetny! Pozwala mi zachować niezmienność moich DTO za pomocą seterów oznaczonych jako prywatne. – Daniel

+3

Działa dla mnie; AutoMapper obecnie nie lubi konstruktorów, w których wszystkie parametry są opcjonalne, więc po prostu używam .ConstructUsing (x => new MyClass()); –

7

należy użyć metody Map który pozwala ustawić miejsce docelowe. Na przykład:

Mapper.CreateMap<ObjectFrom, ObjectTo>() 

var from = new ObjectFrom { Name = "Jon", Age = 25 }; 

var to = Mapper.Map(from, new ObjectTo(param1)); 
0

W momencie pisania tego odpowiedź, AutoMapper zrobi to automatycznie (za pomocą prostego CreateMap<>() rozmowy) dla ciebie, jeśli właściwości dopasować parametry konstruktora. Oczywiście, jeśli coś nie pasuje, to do zrobienia jest użycie .ConstructUsing(...).

public class PersonViewModel 
{ 
    public int Id { get; set; } 

    public string Name { get; set; } 
} 

public class Person 
{ 
    public Person (int id, string name) 
    { 
     Id = id; 
     Name = name; 
    } 

    public int Id { get; } 

    public string Name { get; } 
} 

public class PersonProfile : Profile 
{ 
    public PersonProfile() 
    { 
     CreateMap<PersonProfile, Person>(); 
    } 
} 

Uwaga: Zakładamy używasz Profiles do konfiguracji mapowania automapper.

Kiedy używany jak poniżej, to wytwarza poprawny obiekt:

var model = new PersonModel 
{ 
    Id = 1 
    Name = "John Smith" 
} 

// will correctly call the (id, name) constructor of Person 
_mapper.Map<Person>(model); 

można przeczytać więcej na temat budowy automapper w oficjalnej wiki on GitHub

2

Najlepszą praktyką jest stosowanie udokumentowanych podejść z AutoMapper https://github.com/AutoMapper/AutoMapper/wiki/Construction

public class SourceDto 
{ 
     public SourceDto(int valueParamSomeOtherName) 
     { 
      Value = valueParamSomeOtherName; 
     } 

     public int Value { get; } 
} 

Mapper.Initialize(cfg => cfg.CreateMap<Source, SourceDto>().ForCtorParam("valueParamSomeOtherName", opt => opt.MapFrom(src => src.Value))); 
Powiązane problemy