ホームページ >バックエンド開発 >C#.Net チュートリアル >AutoMapper を使用して Dto と Model 間の自由な変換を実現する (パート 2)
本書は上記の続きです。前回の記事では、AutoMapper を使用して型間の 1-1 マッピングを実装する 2 つの方法 (規約と構成) について説明し、単純な OO マッピングを実行する方法を学びました。このシリーズの最後の記事では、型本体型間のマッピングを実装する方法、2 つの型に複数のマッピング ルールを実装する方法など、ニーズに基づいたいくつかの中レベルのトピックについて説明したいと思います。
[4] 型を型システムにマッピングする
まず、Dto と Model を確認します。 BookDto があり、著者がいて、各著者には独自の連絡先情報があります。ここで質問です。BookDto から最初の著者の Author オブジェクトを取得するにはどうすればよいですか?答えは簡単ですが、単純ではありません。
最も簡単な方法は、前述の CountructUsing を使用して、BookDto から Author へのすべてのフィールドとサブタイプ フィールドのマッピングを指定することです。構成(s => new Author {
;
このアプローチは機能する可能性がありますが、非常に不経済です。 BookDto から Author へのマッピングを最初から実行しており、BookDto から ContactInfo へのマッピングは以前に実装されているため、実際には再度記述する必要はありません。 ContactInfo も含まれる別の Reader 型がある場合、BookDto を Reader にマッピングするときに、BookDto -> ContactInfo ロジックを再度記述する必要があることを想像してください。もう一度想像してみてください。BookDto から Book へのマッピングを実装する場合、BookDto から Author へのマッピング ルールを再度記述する必要があるでしょうか?
したがって、型システム間のこの種のマッピングの理想的なアプローチは、特定の型ごとに単純なマッピングを指定し、複合型をマッピングするときにその単純な型のマッピングを再利用することだと思います。より簡単な言葉で説明してください:
4 つのタイプ A、B、C、D があります。ここで、B = [C, D]。 A -> C、A -> D の場合、A -> B を求めます。
私の解決策は、AutoMapper が提供する IValueResolver を使用することです。 IValueResolver は、フィールド レベルで特定のマッピング ロジックを実装するために AutoMapper によって定義された型です。その定義は次のとおりです。
実際のアプリケーションでは、その汎用サブクラスである ValueResolver を使用して、その抽象メソッドを実装することがよくあります。ターゲットフィールドのタイプ。
opt => opt.ResolveUsing
FirstAuthor In ContactInfoResolver では、ValueResolver を実装し、BookDto -> のロジックを再利用します。 ContactInfo :
C# コード
public class FirstAuthorContactInfoResolver : ValueResolver
{
protected override ContactInfo ResolveCore(BookDto ソース)
{
return Mapper.Map< BookDto、連絡先情報>(ソース);
}
}
すべてが完了しました。同様に、BookDto -> Book を実装できるようになりましたね? BookDto -> Author と BookDto -> Publisher を再利用します。
本当に可能ですか?まだ問題がありそうです。はい、BookDto から 2 人の異なる著者にマッピングする必要があり、フィールド マッピング ルールが異なることがわかります。何をするか?早速最後のトピックに移りましょう。
[5] 2 つのタイプに対して複数セットのマッピング ルールを実装する
一方、もし AutoMapper がそのような機能を提供したら、それはどのようになるだろうかと仮定することもできます。 CreateMap メソッドと Map メソッドは次のように定義する必要があります:
C# コード CreateMap追加パラメータタグ このマッピングを識別するために使用されるラベル。
これを使用すると、次のことが可能になります。C# コード
var firstAuthorMap = Mapper.CreateMap
// BookDto を定義します -> 最初の著者ルール
var SecondAuthorMap = Mapper.CreateMap
// BookDto を定義します -> var firstAuthor = Mapper.Map< ;BookDto, Author>(source, "first");
var SecondAuthor = Mapper.Map
MappingEngine は AutoMapper のマッピング実行エンジンです。実際には、Mapper.CreateMap を呼び出すときに、このデフォルトの MappingEngine に対応するルールを記述し、Mapper.Map を呼び出してオブジェクトを取得します。場合によっては、対応する構成内のルールを実行するためにデフォルトの MappingEngine が使用されます。
要するに、MappingEngine は AutoMapper の「仮想マシン」です。複数の「仮想マシン」を同時に起動し、同じタイプのペアに対して異なるマッピング ルールを異なる「仮想マシン」に配置すると、それらをそれぞれ作成できます。それらを使用する場合は、対応する「仮想マシン」にどのルールを使用するかを問い合わせるだけです。
とにかくやってみよう。まず、MappingEngineProvider クラスを定義し、それを使用してさまざまな MappingEngine を取得します。
{
さまざまなタイプのマッピング ルールをインターフェイス IMapping に抽象化します。
それではMappingEngineProvider のコンストラクター内の対応する MappingEngine に必要なルールを追加します:
C# コード private static Dictionary
public MappingEngineProvider(エンジンエンジン)
{
var config = new Configuration(new TypeMapFactory(), MapperRegistry.AllMappers());
_rules[エンジン].ForEach(r=> r.AddTo(config) ));
_mappingEngine = new MappingEngine(config);
ここでは、可能な MappingEngine を識別するために列挙型エンジンを使用していることに注意してください:C# コード
public enum Engine
基本 = 0、
First、
Second
}
3 つのエンジンを使用します。Basic はすべての Dto ->FirstXXX ルールを配置するために使用され、Second はすべての Dto -> SecondXXX ルールを配置するために使用されます。すべてのマッピング ルールを配置する辞書 _rule も定義し、ルールをさまざまなエンジンに分類します。
残っている唯一のことは、dictionary_rule にマッピングを記入することです。たとえば、最初のエンジンにbookdotopirstauthormingを配置し、2番目のエンジンにbookdotosecondauthormingを入れます;&gt;K New BookdTotofirstAutHormApping (), }}, { Engine.Second, New List & LT }}},};もちろん、使いやすいように、別の MappingEngineProvider オブジェクトをインスタンス化することもできます。事前に:
C# コード public static SimpleMappingEngineProvider First = new MappingEngineProvider(Engine.First); public static SimpleMappingEngineProvider Second = new MappingEngine Provider(Engine.Second) ; これで、これら 2 つのエンジンを使用できるようになります。でBookDto -> をマッピングして 2 人の著者を取得し、それらを Book.Authors: C# コード public class BookDtoToBookMapping : DefaultMapping & LT; = & gt; d.authors, OPT = & GT.ResolveUsing
{
を使用してuse using ‐ ' out out off out out out out way out's'' out's ‐ ‐ ‐ ‐ ‐ protected override List
; ? 新しいリスト<著者> ;() : 新しいリスト<著者> {新しい著者<著者}
: SecondAuthor.IsNull()
}
: new List
最後に、このセクションの冒頭で述べたご多幸をまだ覚えていますか? AutoMapper は実装に役に立たなかったので、自分で実装しましょう。
C# code
public class MyMapper
{
private static readonly Dictionary
eensionエンジン[エンジン] .map&lt; tsource、ttarget&gt;(source);これを実行します:
C# コード var firstAuthor = MyMapper.Mapは次のようにすることもできます:
C# code var book = MyMapper.Map