Verwenden Sie AutoMapper, um eine kostenlose Konvertierung zwischen Dto und Model zu erreichen (Teil 2)

巴扎黑
Freigeben: 2016-12-20 11:31:49
Original
1684 Leute haben es durchsucht

Das Buch wird von oben fortgeführt. Im vorherigen Artikel haben wir zwei Möglichkeiten besprochen, AutoMapper zum Implementieren einer 1:1-Zuordnung zwischen Typen zu verwenden – Konvention und Konfiguration – und gelernt, wie man eine einfache OO-Zuordnung durchführt. Im letzten Artikel dieser Serie möchte ich einige Themen auf mittlerer Ebene basierend auf unseren Anforderungen diskutieren, darunter: wie man die Zuordnung zwischen Typkörpertypen implementiert und wie man mehrere Zuordnungsregeln für zwei Typen implementiert.
【4】Ordnen Sie einen Typ einem Typsystem zu.
Sehen Sie sich zunächst unser Dto und unser Modell an. Wir haben BookDto, wir haben Author und jeder Autor hat seine eigene ContactInfo. Nun eine Frage: Wie bekomme ich das Author-Objekt des Erstautors von BookDto? Die Antwort ist einfach, aber nicht einfach.
Der einfachste Weg besteht darin, das zuvor erwähnte CountructUsing zu verwenden, um die Zuordnung aller Felder und Untertypfelder von BookDto zu Author anzugeben:

C#-Code

var map = Mapper. CreateMap & lt; bookDTO, Autor & gt; (); FirstAuthorBlog,

                                                 🎜>                                                                                                                                                                                                                        


Dieser Ansatz kann funktionieren, ist aber sehr unwirtschaftlich. Da wir die Zuordnung von BookDto zu Author von Grund auf durchführen und die Zuordnung von BookDto zu ContactInfo bereits implementiert wurde, besteht eigentlich keine Notwendigkeit, sie erneut zu schreiben. Stellen Sie sich vor, wenn es einen anderen Reader-Typ gibt, der auch ContactInfo enthält, sollten wir beim Zuordnen von BookDto zu Reader die Logik BookDto -> ContactInfo erneut schreiben? Stellen Sie sich noch einmal vor, wenn wir die Zuordnung von BookDto zu Book implementieren, müssen wir dann die Zuordnungsregeln von BookDto zu Author erneut schreiben?
Ich denke daher, dass für diese Art der Zuordnung zwischen Typsystemen der ideale Ansatz darin besteht, für jeden spezifischen Typ eine einfache Zuordnung anzugeben und dann die Zuordnung des einfachen Typs bei der Zuordnung komplexer Typen wiederzuverwenden. Beschreiben Sie es in einfacherer Sprache:
Wir haben vier Typen A, B, C und D, wobei B = [C, D]. Gegeben sei A ->
Meine Lösung besteht darin, den von AutoMapper bereitgestellten IValueResolver zu verwenden. IValueResolver ist ein von AutoMapper definierter Typ zur Implementierung spezifischer Zuordnungslogik auf Feldebene. Seine Definition lautet wie folgt:

C#-Code

öffentliche Schnittstelle IValueResolver

{

ResolutionResult Resolve(ResolutionResult source);

}


In tatsächlichen Anwendungen verwenden wir häufig seine generische Unterklasse – ValueResolver, und implementieren diese abstrakte Methode:

C#-Code

protected abstract TDestination ResolveCore(TSource source);


wobei TSource der Quelltyp und TDestination der Zieltyp ist.
Zurück zu unserem Beispiel, wir können BookDto jetzt wie folgt zuordnen -> Autor:

C#-Code

var map = Mapper.CreateMap( ) ;

map.ForMember(d => d.Name, opt => opt.MapFrom(s => s.FirstAuthorName))

.ForMember(d => d .Description, opt => opt.MapFrom(s => s.FirstAuthorDescription))

.ForMember(d => d.ContactInfo,

opt => opt. ResolveUsing< ;FirstAuthorContactInfoResolver>()));


In FirstAuthorContactInfoResolver implementieren wir ValueResolver und verwenden BookDto -> ContactInfo-Logik:

C#-Code

öffentliche Klasse FirstAuthorContactInfoResolver : ValueResolver ;(Quelle);

}  

}  

Alles ist erledigt.

Ähnlich können wir jetzt BookDto -> Book implementieren, oder? Durch die Wiederverwendung von BookDto -> Author und BookDto ->

Ist es wirklich möglich? Es scheint immer noch ein Problem zu geben. Ja, wir werden feststellen, dass wir BookDto zwei verschiedenen Autoren zuordnen müssen und ihre Feldzuordnungsregeln unterschiedlich sind. was zu tun? Kommen wir schnell zu unserem letzten Thema.

【5】Implementieren mehrerer Sätze von Zuordnungsregeln für zwei Typen

Unser Problem ist: Für die Typen A und B müssen wir zwei verschiedene A -> B definieren und zulassen, dass sie gleichzeitig verwendet werden. Tatsächlich bietet der aktuelle AutoMapper hierfür keine vorgefertigte Möglichkeit.

Natürlich können wir die Methode „Kurve zur Rettung des Landes“ verwenden – definieren Sie zwei Unterklassen von Autor für den ersten Autor und den zweiten Autor, wie z. B. FirstAuthor und SecondAuthor, und implementieren Sie dann BookDto –> > SecondAuthor-Zuordnung. Allerdings ist diese Methode auch nicht sehr wirtschaftlich. Was ist, wenn es einen dritten Autor oder sogar einen vierten Autor gibt? Für jeden Autor eine Unterklasse „Autor“ definieren?

Andererseits könnten wir genauso gut davon ausgehen, dass, wenn AutoMapper eine solche Funktion bereitstellen würde, wie sie aussehen würde? Die CreateMap-Methode und die Map-Methode sollten wie folgt definiert werden:



C#-Code

CreateMap(string tag)

Map(TSource , String-Tag)

Es gibt einen zusätzlichen Parameter-Tag, der zur Identifizierung des Tags der Zuordnung verwendet wird.

Wenn wir es verwenden, können wir:

C#-Code

var firstAuthorMap = Mapper.CreateMap("first");

// Definiere BookDto -> Autorenregel

var firstAuthor = Mapper.Map(source, „first“);

var secondAuthor = Mapper.Map(source, „second“ );

Leider ist das alles, wenn. Aber das spielt keine Rolle, obwohl AutoMapper diese Tür geschlossen hat, hat er uns eine andere Tür hinterlassen – MappingEngine.

MappingEngine ist die Mapping-Ausführungs-Engine von AutoMapper. Wenn wir Mapper.CreateMap aufrufen, schreiben wir Regeln in die Konfiguration, die dieser Standard-MappingEngine entsprechen Bei Objekten wird die Standard-MappingEngine verwendet, um die Regeln in der entsprechenden Konfiguration auszuführen.

Kurz gesagt, eine MappingEngine ist eine „virtuelle Maschine“ von AutoMapper. Wenn wir mehrere „virtuelle Maschinen“ gleichzeitig starten und unterschiedliche Zuordnungsregeln für dasselbe Typenpaar auf verschiedenen „virtuellen Maschinen“ festlegen, können Sie dies tun Lassen Sie sie ruhig laufen, wenn Sie sie verwenden, fragen Sie einfach die entsprechende „virtuelle Maschine“, welche Regel verwendet werden soll.

Tu es einfach. Zuerst definieren wir eine MappingEngineProvider-Klasse und verwenden sie, um verschiedene MappingEngines zu erhalten:


C#-Code

öffentliche Klasse MappingEngineProvider

{

private readonly MappingEngine _engine;

public MappingEngine Get()

{ >

}

Wir abstrahieren verschiedene Arten von Zuordnungsregeln in Interface-IMapping :

C#-Code

public interface IMapping

{


void AddTo(Configuration config);

}

Fügen Sie dann die erforderlichen Regeln in die entsprechende MappingEngine im Konstruktor von MappingEngineProvider ein:

C#-Code

private static Dictionary> ; _rules=new Dictionary>();


public MappingEngineProvider(Engine engine)

var config = new Configuration(new TypeMapFactory(), MapperRegistry.AllMappers());

_rules[engine]. ForEach(r=> r.AddTo(config)); MappingEngine(config);

}

Beachten Sie, dass wir einen Aufzählungstyp Engine verwendet haben, um mögliche MappingEngines zu identifizieren:

C#-Code

public enum Engine

{

Basic = 0,

First,


Second

}

Wir verwenden 3 Engines: „Basic“ dient zum Platzieren aller grundlegenden Zuordnungsregeln, „First“ wird zum Platzieren aller Dto->

Wir definieren außerdem ein Wörterbuch _rule, das alle Zuordnungsregeln platziert und die Regeln in verschiedene Engines klassifiziert.

Das Einzige, was noch übrig bleibt, ist, die dictionary_rule mit unserer Zuordnung auszufüllen. Zum Beispiel fügen wir BookDtoToFirstAuthorMapping in die erste Engine und BookDtoToSecondAuthorMapping in die zweite Engine ein:

C#-Code

private static readonly Dictionary> 🎜>

neues Wörterbuch>                                                                                                       

new BookDtoToFirstAuthorMapping(),

}

                                                                                                                                                                     >                                                                         {                                                                                                                           Verschiedene MappingEngineProvider-Objekte können im Voraus instanziiert werden:

C#-Code

public static SimpleMappingEngineProvider First = new MappingEngineProvider(Engine.First);

public static SimpleMappingEngineProvider Second = new MappingEngineProvider(Engine.Second);

Jetzt können wir diese 2 Engines verwenden Gleichzeitig beim Zuordnen von BookDto -> Book, um 2 Autoren zu erhalten und sie im Feld „Autoren“ zusammenzustellen:

C#-Code

öffentliche Klasse BookDtoToBookMapping: DefaultMapping 🎜>

{

protected override void MapMembers(IM applyExpression< ;BookDto, Book> map)

{

map.ForMember(d => d.Authors ,

opt => op t.ResolveUsing() ; 🎜>

var secondAuthor = SimpleMappingEngineProvider.Second.Get().Map(source); new List {neuer Autor (), zweiter Autor}


: Secondauthor.isnull ()

? w list & lt;

: neue Liste {ersterAutor, zweiterAutor}; Da AutoMapper uns bei der Implementierung nicht geholfen hat, implementieren wir es selbst:

C#-Code

public class MyMapper

{

private static readonly Dictionary Engines = new Dictionary                                                           >                                                                               Engine.First, MappingEngineProvider.First.Get()},


                                                               Second.Get()},

                                                         🎜> {

return Engines[engine].Mapvar firstAuthor = MyMapper.Map(dto, Engine.First);

var secondAuthor = MyMapper.Map(dto, Engine.Second);

kann auch so sein:

C#-Code

var book = MyMapper.Map(dto);

Postscript: Ich habe festgestellt, dass das Hochladen von Dateien auf Github zu Hause extrem langsam war, also habe ich beschlossen, zuerst meinen Code zu packen und hochzuladen. Jeder kann gerne darauf zurückgreifen.

Verwandte Etiketten:
c#
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage