2016-04-04 7 views
8

ich Klassen wieAutoMapper.Mapper.CreateMap <TSource, TDestination>()‘ist veraltet

class A 
{ 
public int id {get; set;} 
} 

class B 
{ 
public C c {get; set;} 
} 

class C 
{ 
public int id {get; set;} 
public string Name {get; set;} 
} 

Meine Forderung ist Jetzt ID der Klasse A bis ID der Klasse C zu kartieren, was ich bis jetzt zu tun war: Mapper.CreateMap(). ForMember (des => des.C.Id, src => src.MapFrom (x => x.id));

und es funktionierte gut.

Jetzt scheint Auto Mapper hat ihre Implementierung geändert. und ich bekomme Warnung wie folgt:

AutoMapper.Mapper.CreateMap() 'ist veraltet:' Dynamisch erstellen Karten werden in Version 5.0 entfernt. Verwenden Sie eine MapperConfiguration-Instanz und speichern Sie sie bei Bedarf statisch oder Mapper.Initialize. Verwenden Sie CreateMapper, um eine Mapper-Instanz zu erstellen.

Ich muss einige Eigenschaften von Klassen zuordnen, die einen anderen Namen und eine andere Struktur haben. Irgendeine Hilfe dazu.

+2

Werfen Sie einen Blick auf [diese] (http://stackoverflow.com/questions/35256008/automapper-migrating-fro m-static-api) Beitrag. –

+0

@ diiN_s Kommentar sollte Sie in die richtige Richtung weisen, aber wenn Sie immer noch kämpfen, können Sie eine vorherige Version mit NuGet oder über die Eingabeaufforderung installieren: Install-Package AutoMapper -Version 4.1.0 –

Antwort

16

Zuvor

Mapper.CreateMap<Src, Dest>() 
.ForMember(d => d.UserName, opt => opt.MapFrom(/* ????? */)); 

Das Problem hierbei ist, Mapping-Definitionen sind statisch, einmal definiert und während der gesamten Lebensdauer der Anwendung wiederverwendet werden. Vor 3.3 müssten Sie das Mapping bei jeder Anforderung mit dem fest codierten Wert neu definieren. Und da die Mapping-Konfiguration an einem anderen Ort als unserer Mapping-Ausführung erstellt wird, müssen wir einen Laufzeitparameter in unserer Konfiguration einführen und ihn dann während der Ausführung bereitstellen.

Dies wird in zwei Teilen durchgeführt: Die Mapping-Definition, in der wir einen Laufzeitparameter erstellen, und dann zur Ausführungszeit, wenn wir sie bereitstellen. Um die Mapping-Definition mit einem Laufzeitparameter zu erstellen, wir „fake“ einen Verschluss, der eine benannte lokale Variable umfasst:

Mapper.Initialize(cfg => { 

string userName = null; 
cfg.CreateMap<Source, Dest>() 
    .ForMember(d => d.UserName, 
     opt => opt.MapFrom(src => userName) 
    ); 
}); 

Weitere Informationen see this

Für eine oder mehr Klassen

cfg.CreateMissingTypeMaps = true; 
cfg.CreateMap<Source, Dest>() 
    .ForMember(d => d.UserName, 
     opt => opt.MapFrom(src => userName) 
    ); 

cfg.CreateMap<AbcEditViewModel, Abc>(); 
cfg.CreateMap<Abc, AbcEditViewModel>(); 
}); 

In der Mapping-Klasse

IMapper mapper = config.CreateMapper(); 
    var source = new AbcEditViewModel(); 
    var dest = mapper.Map<AbcEditViewModel, Abct>(source); 
+0

es funktioniert gut ABER ES GIBT Ein Problem nach dem. Wenn wir genau dieselben Eigenschaften in zwei Klassen haben als nur Mapper.map (Quelle, Ziel) funktioniert und keine explizite Zuordnung erforderlich. Aber sobald wir verwendet Mapper.Initialize (CFG => { String username = null; cfg.CreateMap () .ForMember (d => d.UserName, opt => opt.MapFrom (src => userName) ); }); Keine andere Mapper.map (Quelle, Ziel) funktioniert (für die Quelle und Ziel haben die gleichen Eigenschaften und Struktur) – Sharad

+0

Sind Sie Quelle und Zielklasse ist generisch? Sie müssen für jede Zuordnung Kombination Karte erstellen –

+0

Nein, ich habe keine generischen Klassen. – Sharad

0

Endlich fand ich die Auflösung. Ich tat: Mapper.Initialize{ Mapping field from source to destination } in der App_start und diese Datei zu dem global.asax hinzufügen -> Application_Start() -> GlobalConfiguration.

Ich brauche eine weitere Zeile in meinem Mapper.Initialize hinzuzufügen, die cfg.CreateMissingTypeMaps = true; ist

Nun wird dieser Code für explizite Abbildung arbeiten, wo zwei Klassen nicht die gleiche Struktur und Namen von Eigenschaften aufweisen.

Abgesehen davon, wenn wir Eigenschaften von zwei Klassen mit der gleichen Struktur zuordnen müssen, funktioniert auch der Code Mapper.map(source, destination), der früher nicht funktionierte.

Lassen Sie mich wissen, wenn jemand Schwierigkeiten mit der Lösung hat. Vielen Dank für die obige Antwort.

0

Ein anderer Weg, die ein bisschen sauberer scheint, ist eine MappingProfile Klasse zu machen, die aus der Profilklasse AutoMapper erbt

public class MappingProfile:Profile 
{ 
    public MappingProfile() 
    { 
     CreateMap<Source1, Destination1>(); 
     CreateMap<Source2, Destination2>(); 
     ... 
    } 
} 

Dann initialisieren Sie die Zuordnung mit Mapper.Initialize(c => c.AddProfile<MappingProfile>()); in Ihrem Startcode

Das erlaubt Sie können das Mapping überall verwenden, indem Sie

anrufen
destination1Collection = source1Collection.Select(Mapper.Map<Source1, Destination1>);