속성 기반 자동 매퍼 기능을 만들고 싶습니다. 도메인 모델 클래스를 DTO 및 역방향으로 매핑해야하지만 DTO의 일부 속성을 절대로 도메인 클래스에 매핑하면 안됩니다. 읽기 전용 속성으로. 서버에서 클라이언트로의 방향 만 허용됩니다.속성에 의한 자동 매퍼 설정
좋아, 그래서 속성을 사용하여 방향을 설정하고자하기 때문에 나는이
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class PersonDTO
{
[MapperDirection(Direction.ClientToServer)]
public string Name { get; set; }
public string Metadata { get; set; }
}
이,이 일
[Flags]
public enum Direction
{
None = 0,
ServerToClient = 1,
ClientToServer = 2,
Both = 4
}
[AttributeUsage(AttributeTargets.Property)]
public class MapperDirectionAttribute : Attribute
{
public Direction Direction { get; }
public MapperDirectionAttribute(Direction direction = Direction.Both)
{
Direction = direction;
}
}
내가 클라이언트에 전용 서버를 허용하는 DTO 클래스에 이름 속성을 장식해야 이름에 대한 방향.
나는 소스에서 모든 값을 복사하려면이 확장자를 가진 매퍼 도우미로가 그래서
public static class MapperExpressions
{
public static IMappingExpression<TSource, TDestination> OnlyIfClientToServer<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
var sourceType = typeof(TSource);
var props = sourceType.GetMembers().Where(prop => prop.IsDefined(typeof(MapperDirectionAttribute), false));
foreach (var property in props)
{
var attribute = property.GetCustomAttribute<MapperDirectionAttribute>();
var allow = attribute.Direction == Direction.ClientToServer || attribute.Direction == Direction.Both;
if (!allow)
{
// THIS DOESN'T WORK FOR SOURCE MEMBER
// AND CAN'T BE USED FOR DESTINATION MEMBER (BECAUSE OF MISSING PROPERTIES)
expression.ForSourceMember(property.Name, opt => opt.Ignore());
}
}
return expression;
}
}
매퍼 초기화를 설정하는 속성에 따라 대상으로하는
// Init mapper
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Person, PersonDTO>();
cfg.CreateMap<PersonDTO, Person>()
.OnlyIfClientToServer();
//.ForSourceMember(src => src.Name, src => src.Ignore()) // DOESN'T WORK
//.ForMember(dst => dst.Name, dst => dst.Ignore()); // WORKS, BUT DON'T WANT EXPLICIT DEFINITION
});
그리고 콘솔 응용 프로그램의 일부입니다
// Map Domain -> ViewModel
var person = new Person { Id = 1, Name = "Default Name From Domain" };
var personDto = Mapper.Map<PersonDTO>(person);
Console.WriteLine($"Person: Id = '{person.Id}', Name = '{person.Name}'");
Console.WriteLine($"PersonDTO: Name = '{personDto.Name}', Metadata = '{personDto.Metadata}'");
Console.WriteLine();
// Map ViewModel -> Domain
personDto.Name = "Changed from DTO";
personDto.Metadata = "Custom metadata from DTO";
Mapper.Map(personDto, person);
Console.WriteLine($"PersonDTO: Name = '{personDto.Name}', Metadata = '{personDto.Metadata}'");
Console.WriteLine($"Person: Id = '{person.Id}', Name = '{person.Name}'");
Console.ReadLine();
이제 문제가 발생합니다.
알고 싶습니다. 왜 ForSourceMember이 예상대로 작동하지 않습니까? 어떻게 소스 회원을 사용하여 매핑을 방지하기 위해?
ForMember 매핑을 사용 할 수 없기 때문에 원본이 대상으로되어 있기 때문에 대상은 도메인 모델 일뿐입니다. 다른 문제는 DTO 클래스의 모든 속성이 도메인 클래스에있는 것은 아니므로 내 확장은 물론 예외입니다.
복제 된 속성을 유지 관리하는 방법은 입니다. CreateMap <>이지만 구성 코드에 모든 속성을 추가하고 싶지는 않습니다. 속성을 설정하는 것이 좋습니다.
내 논리를 AutoMapper 확장으로 유지하기 위해 내 솔루션을 수정하는 방법을 아는 사람이 있습니까?