我有以下实体模型
public class Blog
{
public int Id { get; set;}
public string Title { get; set; }
public string Body { get; set; }
[ForeignKey("Category")]
public int? CategoryId { get; set; }
public virtual Category Category { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
public class Category
{
public int Id { get; set;}
public string Name { get; set; }
}
public class Comment
{
public int Id { get; set;}
public string Title { get; set; }
public string Body { get; set; }
[ForeignKey("Blog")]
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
然后我有以下视图模型,我想告诉 AutoMapper 将Blog
对象映射到属性需要来自的BlogViewModel
通知中,并且每个都需要转换为使用有机约定。CategoryName
Blog.Category.Name
Comment
Blog.Comments
CommentViewModel
我目前在运行时使用反射为任何实现ICustomMap
接口的类设置映射。请阅读该Transfer(IMapper mapper)
方法的代码中的注释。
public class BlogViewModel : ICustomMapFrom
{
public int Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public string MyCatName { get; set; }
public IEnumerable<CommentViewModel> Comments { get; set; }
// **IMPORTANT NOTE**
// This method is called using reflection when the on Application_Start() method.
// If IMapper is the wrong Interface to pass, I can change
// the implementation of ICustomMap
// I assumed that `IMapper` is what is needed to add configuration at runtime.
public void Transfer(IConfigurationProvider config)
{
// How to I do the custom mapping for my MyCatName and Comments?
// I need to use the config to create the complex mapping
// AutoMapper.Mapper.Map(typeof(Blog), typeof(BlogViewModel));
}
}
最后这是我的CommentViewModel
public class CommentViewModel : IMapFrom<Comment>
{
public int Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
}
如何告诉 AutoMapper 如何映射 CategoryName 和 Comments?
更新
这是我将如何创建映射。我将有以下 3 个接口
public interface IMap
{
}
public interface IMapFrom<T> : IMap
{
}
public interface ICustomMapFrom : IMap
{
void Map(IConfigurationProvider config);
}
然后在 Global.cs 文件中
我会Run
在启动时执行该方法。基本上,此方法将扫描程序集并注册我想使用接口注册的类。
public class ConfigureAutoMapper
{
public void Run()
{
var types = AssemblyHelpers.GetInternalAssemblies()
.SelectMany(x => x.GetTypes())
.Where(x => x.IsClass && !x.IsAbstract && !x.IsInterface && typeof(IMap).IsAssignableFrom(x))
.ToList();
RegisterStandardMappings(types);
RegisterCustomMappings(types);
}
private static void RegisterStandardMappings(IEnumerable<Type> types)
{
foreach (Type type in types)
{
if(type.IsGenericType && typeof(IMapFrom<>).IsAssignableFrom(type))
{
AutoMapper.Mapper.Map(type.GetGenericArguments()[0], type);
}
}
}
private static void RegisterCustomMappings(IEnumerable<Type> types)
{
foreach (Type type in types)
{
if (typeof(ICustomMapFrom).IsAssignableFrom(type))
{
ICustomMapFrom map = (ICustomMapFrom)Activator.CreateInstance(type);
var t = AutoMapper.Mapper.Configuration;
map.Map(Mapper.Configuration);
}
}
}
}