Ich beginne zu implementieren AutoMapper, zuerst habe ich es mit Castle.Windsor zu integrieren, die ich bereits verwende. Jetzt habe ich eine Post
Einheit, die ich entweder einer LinkPostModel
oder einer ImagePostModel
zuordnen möchte. Beide erben von PostModel
AutoMapper Map zu verschiedenen Typen basierend auf einer Enum?
1) Dies ist, was habe ich bisher:
public class PostModelFromPostEntityConverter : ITypeConverter<Post, PostModel>
{
private readonly IPostService postService;
public PostModelFromPostEntityConverter(IPostService postService)
{
if (postService == null)
{
throw new ArgumentNullException("postService");
}
this.postService = postService;
}
public PostModel Convert(ResolutionContext context)
{
Post post = (Post)context.SourceValue;
Link link = post.Link;
if (link.Type == LinkType.Html)
{
return new LinkPostModel
{
Description = link.Description,
PictureUrl = link.Picture,
PostId = post.Id,
PostSlug = postService.GetTitleSlug(post),
Timestamp = post.Created,
Title = link.Title,
UserMessage = post.UserMessage,
UserDisplayName = post.User.DisplayName
};
}
else if (link.Type == LinkType.Image)
{
return new ImagePostModel
{
PictureUrl = link.Picture,
PostId = post.Id,
PostSlug = postService.GetTitleSlug(post),
Timestamp = post.Created,
UserMessage = post.UserMessage,
UserDisplayName = post.User.DisplayName
};
}
return null;
}
}
Offensichtlich ist der Punkt AutoMapper bei der Implementierung wiederholen Codes wie folgt zu entfernen, so wie sollte ich die gemeinsame Sachen kartieren , bevor meine benutzerdefinierten Regeln (wie die if-Klausel)
im Idealfall würde ich will, dass diese etwas sein, wie das Hinzufügen von:
public class PostModelFromPostEntityConverter : ITypeConverter<Post, PostModel>
{
[...]
public PostModel Convert(ResolutionContext context)
{
Post post = (Post)context.SourceValue;
Link link = post.Link;
if (link.Type == LinkType.Html)
{
return Mapper.Map<Post, LinkPostModel>(post);
// and a few ForMember calls?
}
else if (link.Type == LinkType.Image)
{
return Mapper.Map<Post, ImagePostModel>(post);
// and a few ForMember calls?
}
return null;
}
}
2) Nachdem diese Zuordnung abgeschlossen ist. Ich habe eine „Eltern“ Mapping, wo Ich brauche eine IEnumerable<Post>
das folgende Modell zur Karte:
public class PostListModel : IHasOpenGraphMetadata
{
public OpenGraphModel OpenGraph { get; set; } // og:model just describes the latest post
public IList<PostModel> Posts { get; set; }
}
Also im Grunde würde ich brauche einen anderen TypeConverter
(rechts?), die mir die Beiträge Liste Karte ermöglicht es zuerst und dann auf die diese ich habe og:model
schaffen, aber es fühlt sich irgendwie klobig, halte ich es besser sein könnte:
public class PostListModelFromPostEntityEnumerableConverter : ITypeConverter<IEnumerable<Post>, PostListModel>
{
public PostListModel Convert(ResolutionContext context)
{
IEnumerable<Post> posts = (IEnumerable<Post>)context.SourceValue;
PostListModel result = new PostListModel
{
Posts = posts.Select(Mapper.Map<Post, PostModel>).ToList()
};
Post first = posts.FirstOrDefault();
result.OpenGraph = Mapper.Map<Post, OpenGraphModel>(first);
return result;
}
}
3) Ich habe den Code noch nicht ausgeführt, daher fällt mir eine andere Frage ein, und deshalb werden Mappings in Konvertern nicht stark typisiert?
IEnumerable<Post> posts = (IEnumerable<Post>)context.SourceValue;
wo es tatsächlich
IEnumerable<Post> posts = context.SourceValue;