책은 위에서 이어집니다. 이전 기사에서는 AutoMapper를 사용하여 유형 간 1-1 매핑(Convention 및 Configuration)을 구현하는 두 가지 방법에 대해 논의하고 간단한 OO 매핑을 수행하는 방법을 배웠습니다. 이 시리즈의 마지막 기사에서는 유형 본문 유형 간의 매핑을 구현하는 방법과 두 유형에 대한 여러 매핑 규칙을 구현하는 방법을 포함하여 우리의 요구에 따라 몇 가지 중간 수준 주제에 대해 논의하고 싶습니다.
【4】타입을 타입 시스템으로 매핑
먼저 Dto와 모델을 검토하세요. BookDto가 있고 Author가 있으며 각 Author에는 고유한 ContactInfo가 있습니다. 이제 질문이 있습니다. BookDto에서 첫 번째 저자의 Author 개체를 가져오는 방법은 무엇입니까? 대답은 간단하지만 간단하지는 않습니다.
가장 간단한 방법은 앞서 언급한 CountructUsing을 사용하여 BookDto에서 Author로의 모든 필드 및 하위 유형 필드 매핑을 지정하는 것입니다.
C# 코드
var map = Mapper. CreateMap
map.ConstructUsing(s => new Author
Name = s.FirstAuthorName,
~ 블로그 = s. 제1저자 블로그,
🎜>
~ ~
이 접근 방식은 효과가 있을 수 있지만 매우 비경제적입니다. BookDto에서 Author로의 매핑을 처음부터 수행하고 있고 BookDto에서 ContactInfo로의 매핑이 이전에 구현되었기 때문에 실제로 다시 작성할 필요가 없습니다. ContactInfo도 포함하는 다른 Reader 유형이 있는 경우 BookDto를 Reader에 매핑할 때 BookDto -> ContactInfo 논리를 다시 작성해야 할까요? BookDto에서 Book으로의 매핑을 구현한다면 BookDto에서 Author로의 매핑 규칙을 다시 작성해야 합니까?
그래서 이런 종류의 유형 시스템 간 매핑을 위해서는 각 특정 유형에 대해 단순 매핑을 지정한 다음 복합 유형을 매핑할 때 단순 유형의 매핑을 재사용하는 것이 이상적인 접근 방식이라고 생각합니다. 더 간단한 언어로 설명하세요.
A, B, C, D의 네 가지 유형이 있습니다. 여기서 B = [C, D]입니다. A -> C, A -> D가 주어지면 A -> B를 찾으세요.
제 솔루션은 AutoMapper에서 제공하는 IValueResolver를 사용하는 것입니다. IValueResolver는 필드 수준에서 특정 매핑 논리를 구현하기 위해 AutoMapper에서 정의한 유형입니다.
C# 코드
공용 인터페이스 IValueResolver
{
ResolutionResult Resolve(ResolutionResult source)
}
실제 애플리케이션에서는 종종 일반 하위 클래스인 ValueResolver를 사용하고 이를 구현합니다. 추상 메서드:
C# 코드
protected abstract TDestination ResolveCore(TSource 소스)
여기서 TSource는 소스 유형이고 TDestination은 대상 필드입니다.
예제로 돌아가서 이제 다음과 같이 BookDto를 매핑할 수 있습니다. -> Author:
C# 코드
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>()));
FirstAuthorContactInfoResolver에서 ValueResolver를 구현하고 BookDto를 재사용합니다. -> ContactInfo 로직:
C# 코드
FirstAuthorContactInfoResolver : ValueResolver
{
protected override ContactInfo ResolveCore(BookDto source)
{
return Mapper.Map< ;BookDto, ContactInfo> ;(출처);
}
}
모든 작업이 완료되었습니다.
마찬가지로 이제 BookDto -> Book을 구현할 수 있죠? BookDto -> Author 및 BookDto ->
정말 가능할까요? 아직 문제가 있는 것 같습니다. 예, BookDto에서 두 명의 다른 작성자로 매핑해야 하며 해당 필드 매핑 규칙이 다르다는 것을 알게 될 것입니다. 무엇을 해야 할까요? 마지막 주제로 빠르게 넘어가겠습니다.
【5】두 가지 유형에 대한 여러 매핑 규칙 세트 구현
문제는 유형 A와 B에 대해 2개의 서로 다른 A -> B를 정의하고 동시에 사용할 수 있도록 허용해야 한다는 것입니다. 실제로 현재 AutoMapper는 이를 수행하기 위한 미리 만들어진 방법을 제공하지 않습니다.
물론 "국가를 구하기 위한 곡선" 방법을 사용할 수 있습니다. FirstAuthor 및 SecondAuthor와 같이 첫 번째 저자와 두 번째 저자에 대해 Author의 두 하위 클래스를 정의한 다음 BookDto -> > 하지만 이 방법 역시 그다지 경제적이지는 않습니다. 세 번째 저자나 네 번째 저자가 있는 경우에는 어떻게 되나요? 각 저자에 대한 Author 하위 클래스를 정의하시겠습니까?
반면에 AutoMapper가 그러한 기능을 제공한다면 어떤 모습일까요? CreateMap 메서드와 Map 메서드는 다음과 같이 정의되어야 합니다.
C# 코드
CreateMap
Map
매핑의 태그를 식별하는 데 사용되는 추가 매개변수 태그가 있습니다.
이를 사용하면 다음을 수행할 수 있습니다.
C# 코드
var firstAuthorMap = Mapper.CreateMap
// BookDto 정의 -> 첫 번째 작성자 규칙
var secondAuthorMap = Mapper.CreateMap
// BookDto 정의 -> 작성자 규칙
var firstAuthor = Mapper.Map
var secondAuthor = Mapper.Map
안타깝지만 이것이 전부입니다. AutoMapper가 이 문을 닫았지만 우리에게는 MappingEngine이라는 또 다른 문이 남았습니다.
MappingEngine은 AutoMapper의 매핑 실행 엔진입니다. 실제로 Mapper에는 기본 MappingEngine이 있습니다. Mapper.CreateMap을 호출하면 이 기본 MappingEngine을 호출한 후 Configuration에 규칙을 작성합니다. 객체의 경우 기본 MappingEngine이 해당 구성의 규칙을 실행하는 데 사용됩니다.
간단히 말하면 MappingEngine은 AutoMapper의 "가상 머신"입니다. 동시에 여러 "가상 머신"을 시작하고 서로 다른 "가상 머신"에 동일한 유형 쌍에 대해 서로 다른 매핑 규칙을 적용하면 다음을 수행할 수 있습니다. 평화롭게 실행되도록 하세요. 사용할 때 해당 "가상 머신"에 어떤 규칙을 사용할지 물어보세요.
그냥 하세요. 먼저 MappingEngineProvider 클래스를 정의하고 이를 사용하여 다양한 MappingEngine을 얻습니다.
C# 코드
public class MappingEngineProvider
{
private readonly MappingEngine _engine;
public MappingEngine Get()
{ >
}다양한 유형의 매핑 규칙을 인터페이스 IMapping으로 추상화합니다. :
C# 코드
공용 인터페이스 IMapping
그런 다음 필요한 규칙을 MappingEngineProvider 생성자의 해당 MappingEngine에 넣습니다.
C# 코드
private static Dictionary
열거형 엔진을 사용하여 가능한 MappingEngine을 식별했습니다.
C# 코드
공개 열거형 엔진
우리는 3개의 엔진을 사용하는데, Basic은 모든 기본 매핑 규칙을 배치하는 데 사용되고, First는 모든 Dto -> FirstXXX 규칙을 배치하는 데 사용되며, Second는 모든 Dto -> SecondXXX 규칙을 배치하는 데 사용됩니다.
또한 모든 매핑 규칙을 배치하는 사전 _rule을 정의하고 규칙을 여러 엔진으로 분류합니다.남은 유일한 일은 매핑으로 Dictionary_rule을 채우는 것입니다. 예를 들어 첫 번째 엔진에 BookDtoToFirstAuthorMapping을 배치하고 두 번째 엔진에 BookDtoToSecondAuthorMapping을 배치합니다.
C# 코드
private static readonly Dictionary
새 사전>
Engine.First, 새 목록
~
new BookDtoToFirstAuthorMapping(),
}
> { 다양한 MappingEngineProvider 개체를 미리 인스턴스화할 수 있습니다.
C# 코드 public static SimpleMappingEngineProvider First = new MappingEngineProvider(Engine.First); public static SimpleMappingEngineProvider Second = new MappingEngineProvider(Engine.Second)이제 이 두 엔진을 사용할 수 있습니다. BookDto를 매핑할 때 -> Book을 사용하여 2명의 Author를 필드로 조립합니다. Authors:
C# 코드 public class 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
: Secondauthor.isnull()
? w 목록 & lt; {firstautHor}
: new List
마지막으로, 이 섹션의 시작 부분에서 언급한 좋은 점을 기억하시나요? AutoMapper는 구현에 도움이 되지 않았으므로 직접 구현해 보겠습니다.
C# 코드 public class MyMapper
{
Engine.First, MappingEngineProvider.First.Get()},
두 번째.Get()},
public static TTarget Map
은 다음과 같을 수도 있습니다:
C# 코드 var book = MyMapper.Map추첨: 집에서 Github에 파일을 업로드하는 것이 매우 느린 것을 발견하여 먼저 코드를 패키지하여 업로드하기로 결정했습니다.