AutoMapper是否基于枚举映射到其他类型? [英] AutoMapper Map to different type based on an enum?
问题描述
我开始实现 AutoMapper ,首先我设法将其与Castle.Windsor集成在一起我已经在用了.现在,我有一个Post
实体,我想将其映射到LinkPostModel
或ImagePostModel
.两者都继承自PostModel
I'm starting to implement AutoMapper, first I managed to integrate it with Castle.Windsor, which I'm already using. Now I have a Post
entity which I want to map to either a LinkPostModel
or an ImagePostModel
. Both inherit from PostModel
1)这是我到目前为止的内容:
1) This is what I have so far:
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;
}
}
显然,实现 AutoMapper 的目的是删除这样的重复代码,所以我应该如何映射常见的东西,然后再添加我的自定义规则(例如if子句)
Obviously the point in implementing AutoMapper is removing repeat code like this, so how am I supposed to map the common stuff, before adding my custom rules (such as the if-clause)
理想情况下,我希望它类似于:
Ideally I'd want this to be something like:
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)此映射完成之后.我有一个父"映射,需要在其中映射IEnumerable<Post>
以下模型:
2) After this mapping is complete. I have a "parent" mapping, where I need to map an IEnumerable<Post>
the following model:
public class PostListModel : IHasOpenGraphMetadata
{
public OpenGraphModel OpenGraph { get; set; } // og:model just describes the latest post
public IList<PostModel> Posts { get; set; }
}
所以基本上我需要另一个TypeConverter
(对吗?),这使我可以先映射帖子列表,然后创建og:model
So basically I'd need another TypeConverter
(right?), which allows me to map the posts list first, and then create the og:model
我有这个,但感觉有点笨拙,我觉得可能会更好:
I have this, but it feels kind of clunky, I feel it could be better:
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)我实际上还没有运行代码,所以又想到了一个问题,那就是为什么转换器中的映射类型不是很强?
3) I didn't actually run the code yet, so another question comes to mind, and that is why aren't mappings strongly typed in converters?
IEnumerable<Post> posts = (IEnumerable<Post>)context.SourceValue;
实际上可能在哪里
IEnumerable<Post> posts = context.SourceValue;
推荐答案
试图获取死灵法师徽章.
如今,通过使用ConstructUsing
函数可以轻松地解决此任务,应该在提供的操作中填充指定字段,但是所有公共字段都将转到映射的ForMember
执行中.在这种情况下,集合不需要任何其他逻辑/映射配置.具有属性collection类型的类.
Trying to get Necromancer badge.
Nowadays this task can be solved much easier with using ConstructUsing
function specifc fields should be filled in the provided action, but all the common fields will go to ForMember
execution of the mapping. Collections in this case doesn't requires any additional logic/mapping configurations. Classes that has a property of type collection as well.
cfg.CreateMap<Post, PostModel>()
.ConstructUsing(p =>
{
switch (p.Type)
{
case LinkType.Html: return new LinkPostModel
{
Title = p.Description
// other specific fields
};
case LinkType.Image: return new ImagePostModel
{
// other specific fields
};
}
return null;
})
.ForMember(x => x.PostId, m => m.MapFrom(p => p.Id));
cfg.CreateMap<PostList, PostListModel>();
这篇关于AutoMapper是否基于枚举映射到其他类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!