如何避免要求这样的代码:
public static class BusinessLogicAutomapper
{
public static bool _configured;
public static void Configure()
{
if (_configured)
return;
Mapper.CreateMap<Post, PostModel>();
_configured = true;
}
}
在我的BL程序集中,并且必须在我的MVC应用程序中从Configure()
调用Global.asax
?
我的意思是,我期待这样的电话:
public PostModel GetPostById(long id)
{
EntityDataModelContext context = DataContext.GetDataContext();
Post post = context.Posts.FirstOrDefault(p => p.PostId == id);
PostModel mapped = Mapper.Map<Post, PostModel>(post);
return mapped;
}
到Mapper.Map<TIn,TOut>
生成映射器(如果它不存在),而不是必须自己手动创建它(我甚至不应该知道关于这个内部工作)。如何以声明方式为AutoMapper创建映射器?
需要一个对AutoMapper很自然的解决方案,但是为了避免这种初始化,扩展或一些架构改变也会起作用。
我正在使用MVC 3,.NET 4,没有IoC / DI(至少还有)
答案 0 :(得分:2)
我完全误解了你在原来的答案中想要做的事情。您可以通过使用反射实现AutoMapper的部分功能来完成您想要的任务。实用性非常有限,扩展得越多,就越像AutoMapper,所以我不确定它有什么长期价值。
我确实使用了一个小实用程序,就像你想要自动化审计框架一样,将数据从实体模型复制到相关的审计模型。我在开始使用AutoMapper之前创建了它并且没有替换它。我把它称为ReflectionHelper,下面的代码是对它的修改(来自内存) - 它只处理简单的属性,但可以根据需要调整以支持嵌套模型和集合。它是基于约定的,假设具有相同名称的属性对应且具有相同的类型。复制到的类型上不存在的属性将被忽略。
public static class ReflectionHelper
{
public static T CreateFrom<T,U>( U from )
where T : class, new
where U : class
{
var to = Activator.CreateInstance<T>();
var toType = typeof(T);
var fromType = typeof(U);
foreach (var toProperty in toType.GetProperties())
{
var fromProperty = fromType.GetProperty( toProperty.Name );
if (fromProperty != null)
{
toProperty.SetValue( to, fromProperty.GetValue( from, null), null );
}
}
return to;
}
用作
var model = ReflectionHelper.CreateFrom<ViewModel,Model>( entity );
var entity = ReflectionHelper.CreateFrom<Model,ViewModel>( model );
<强>原始强>
我在静态构造函数中进行映射。第一次引用类时初始化映射器而不必调用任何方法。但是,我不会将逻辑类设置为静态,以增强其可测试性以及使用它作为依赖项的类的可测试性。
public class BusinessLogicAutomapper
{
static BusinessLogicAutomapper
{
Mapper.CreateMap<Post, PostModel>();
Mapper.AssertConfigurationIsValid();
}
}
答案 1 :(得分:1)
查看Automapper个人资料。
我在Global.asax中设置了这个设置 - 它静态运行一次,所以一切都在运行时准备就绪。
我还有1个单元测试,覆盖所有地图以检查它们是否正确。
一个很好的例子是Ayendes Raccoon Blog