【问题标题】:AutoMapper how to avoid initializationAutoMapper如何避免初始化
【发布时间】:2011-11-13 23:08:07
【问题描述】:

如何避免需要这样的代码:

public static class BusinessLogicAutomapper
{
    public static bool _configured;

    public static void Configure()
    {
        if (_configured)
            return;

        Mapper.CreateMap<Post, PostModel>();
        _configured = true;
    }
}

在我的 BL 程序集中,并且必须在我的 MVC 应用程序中从我的 Global.asax 调用 Configure()

我的意思是,我期待这样的电话:

    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&lt;TIn,TOut&gt; 来生成映射器(如果它不存在),而不必自己手动创建它(我什至不应该知道这个内部工作)。如何以声明方式为 AutoMapper 创建映射器?

需要一个对 AutoMapper 来说很自然的解决方案,但为了避免这种初始化而进行的扩展或一些架构更改也会起作用。

我正在使用 MVC 3、.NET 4,并且没有 IoC/DI(至少还没有)

【问题讨论】:

  • 如果您没有 CreateMap 配置调用,当 Post -> PostModel 地图中的某些内容未对齐时会发生什么?也就是说,你在 Post 上重命名了某个东西,但在 PostModel 上没有重命名?

标签: c# automapper


【解决方案1】:

我完全误解了你在我原来的答案中试图做的事情。您可以通过使用反射实现 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();
    }
}

【讨论】:

    【解决方案2】:

    查看 Automapper 配置文件。

    我的 Global.asax 中有这个设置 - 它静态运行一次,所以一切都在运行时设置好了。

    我还有 1 个单元测试,涵盖所有地图以检查它们是否正确。

    Ayendes Raccoon 博客就是一个很好的例子

    https://github.com/ayende/RaccoonBlog

    【讨论】:

      猜你喜欢
      • 2017-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      • 1970-01-01
      • 2021-10-28
      • 1970-01-01
      • 2015-04-15
      相关资源
      最近更新 更多