Nei casi in cui i miei setter di destinazione sono privati, potrei voler eseguire il mapping all'oggetto utilizzando il costruttore dell'oggetto di destinazione. Come lo faresti usando Automapper?Automapper: come mappare i parametri del costruttore anziché i setter di proprietà
risposta
Usa ConstructUsing
questo vi permetterà di specificare quali il costruttore da utilizzare durante la mappatura. ma poi tutte le altre proprietà verranno automaticamente mappate in base alle convenzioni.
Si noti inoltre che questo è diverso da ConvertUsing
in quella conversione utilizzando non continuerà a mappare tramite le convenzioni, ma ti darà invece il pieno controllo della mappatura.
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; }
}
}
Si dovrebbe utilizzare il metodo Map
che consente di impostare la destinazione. Per esempio:
Mapper.CreateMap<ObjectFrom, ObjectTo>()
var from = new ObjectFrom { Name = "Jon", Age = 25 };
var to = Mapper.Map(from, new ObjectTo(param1));
Al momento della stesura di questa risposta, automapper farà automaticamente (con una semplice chiamata CreateMap<>()
) per voi se le proprietà corrispondono ai parametri del costruttore. Ovviamente, se le cose non coincidono, usare .ConstructUsing(...)
è la strada da percorrere.
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>();
}
}
Nota: Questo assume che si sta utilizzando Profiles di impostare le vostre mappature automapper.
Quando viene utilizzato come qui di seguito, questo produce l'oggetto corretto:
var model = new PersonModel
{
Id = 1
Name = "John Smith"
}
// will correctly call the (id, name) constructor of Person
_mapper.Map<Person>(model);
Si può leggere di più sulla costruzione automapper nella ufficiale wiki on GitHub
La pratica migliore è quella di utilizzare approcci documentati da 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)));
- 1. Automapper dovrebbe funzionare con i setter privati OOB?
- 2. Utilizzando automapper per mappare i tipi sconosciuti
- 3. Mappare i parametri URI alle proprietà dell'oggetto parametro?
- 4. Proprietà mappatura AutoMapper con private setter
- 5. Come mappare i parametri lambda in TakeWhile?
- 6. AutoMapper ed ereditarietà - Come mappare?
- 7. Iniezione del costruttore rispetto all'iniezione setter per proprietà Parent
- 8. Quali sono i vantaggi dell'utilizzo di automapper?
- 9. Come passare i valori di contesto su Automapper Map?
- 10. Come utilizzare Automapper costruire oggetto senza costruttore di default
- 11. Mappare solo poche proprietà invece di tutte usando Automapper
- 12. Come sovrascrivere i parametri del costruttore in Sphinx con autodoc?
- 13. AutoMapper utilizzando il costruttore errato
- 14. Come mappare una proprietà senza setter e nessuna proprietà di supporto fluente con NHibernate?
- 15. Costruttore con tutte le proprietà di classe o costruttore predefinito con setter?
- 16. Parametri del costruttore ConcurrentHashMap?
- 17. Devo convalidare i parametri nel costruttore?
- 18. Esiste un modo generico di utilizzare ValueResolver di AutoMapper per mappare i valori di EntityKey per le Entità EF?
- 19. Perché i setter e i getter della proprietà si scontrano con i metodi get_X e set_X?
- 20. Proprietà astratte o parametri del costruttore di base?
- 21. ignorando i getter/setter ereditari
- 22. Come mappare un oggetto complesso con Automapper?
- 23. Può Automapper ignorare i metodi di annullamento?
- 24. AutoMapper TypeConverter costruttore personalizzato
- 25. Compojure: come mappare Parametri query
- 26. Mappare un insieme raggruppato utilizzando automapper
- 27. Passare i parametri per mappare le funzioni in CouchDb
- 28. Automapper non riuscendo a mappare l'IEnumerable
- 29. I setter della proprietà .Net vengono mai chiamati implicitamente?
- 30. Form Zend: come passare i parametri nel costruttore?
Suppongo che "ConstructUsing" debba essere in una versione più recente di automapper rispetto a stai usando. Grazie Jon – jlembke
Mille grazie per questo esempio Jon. "ConstructUsing" è fantastico! Mi consente di mantenere immutabili i miei DTO con i setter contrassegnati come privati. – Daniel
Per me è un piacere; Al momento AutoMapper non apprezza i costruttori in cui tutti i parametri sono opzionali, quindi uso semplicemente .ConstructUsing (x => new MyClass()); –