2016-06-01 43 views
1

我需要帮助,看看AutoMapper是否可以做到这一点。我的代码已经被简化了,但它可以解决问题。使用AutoMapper运行功能,根据其他参数设置多个属性

public class SourceObject 
{ 
    public string Property1 { get; set; } 
    public string Property2 { get; set; } 
    public string Property3 { get; set; } 

} 

public class DestinationObject 
{ 
    public string Property1 { get; set; } 
    public string Property2 { get; set; } 
    public string Property3 { get; set; } 
    public string Property4 { get; set; } 
    public string Property5 { get; set; } 
    public string Property6 { get; set; } 
} 

var vm = new ViewModel 
{ 
    Objects = Mapper.Map<IList<SourceObject>, IEnumerable<DestinationObject>>(dests) 
}; 

foreach (var destObj in vm.Objects) 
{ 
    Utility.SetupProperties(destObj, new AnotherDependency(), destObj.Property3, 
     someFlag, anotherFlag); 
} 

Property1Property3是建立由AutoMapper目前。然后我必须遍历DestinationObjects的列表来设置Property4Property6带一个函数,一些额外的标志。我明白这可能不是AutoMapper的用途,但我真的希望避免两次循环对象(一次是通过AutoMapper,一次是我自己的)。静态SetupProperties功能在其他地方使用,所以我想保留它。 AutoMapper可以设置它吗?感谢您提前提供任何帮助。

+0

您可以用[前SourceObject“和”DestinationObject“之间的映射关系(https://github.com/AutoMapper/AutoMapper/wiki/Before-and-after-map-actions)? – AGB

+0

感谢您的回复。就像MindingData建议的那样,但不幸的是,我不能通过使用Before和After Actions来将其他参数传递到映射中。 – Will

回答

0

这真的取决于发生了什么里面Utility.SetupProperties,但也可以通过使用之前和Automapper映射操作后,有一点逻辑的更复杂的映射情况:https://github.com/AutoMapper/AutoMapper/wiki/Before-and-after-map-actions

Mapper.Initialize(cfg => { 
    cfg.CreateMap<SourceObject, DestinationObject>() 
    .BeforeMap((src, dest) => 
    { 
     //Do some work here and set properties. 
    }) 
}); 
+0

感谢您的回应。 SetupProperties查看输入并尝试确定其余属性应该是什么。我阅读了映射前后的操作,但我不认为我们可以在运行时将其他标志传递给它,我们可以吗? – Will

+0

的确如此。不幸的是你不能这么做(据我所知)。要做到这一点,你需要在Mapper.Map上有一个“params”输入来了解它应该考虑的其他字段。 – MindingData

0

通常,您可以使用AfterMap并通过闭包捕获您想要传入的其他参数(如第二个wiki示例中所示)。但是,由于您要在集合之间进行转换,因此在这种情况下,我认为没有一种干净的方法来处理每个项目。

我已经做了一些挖掘,并且我认为您可以使用ITypeConverter<TSource, TDestination>来完成您尝试的转换。

我不得不做一些猜测实施和使用案例Utility.SetupProperties等,但我认为概念控制台应用程序的以下证明应说明如何实现自定义转换:

using System; 
using System.Collections.Generic; 
using AutoMapper; 

namespace ConsoleApplication 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      var sourceObjects = new SourceObject[] { 
       new SourceObject{Property1 = "prop 1A"}, 
       new SourceObject{Property2 = "Prop 2B"}, 
       new SourceObject{Property3 = "Prop 3C"}}; 

      var someFlag = true; 
      var anotherFlag = false; 

      Mapper.Initialize(cfg => 
      { 
       cfg.CreateMap<SourceObject, DestinationObject>().ConvertUsing<CustomConverter>(); 
      }); 

      var vm = new ViewModel 
      { 
       Objects = Mapper.Map<IList<SourceObject>, IEnumerable<DestinationObject>>(sourceObjects, opts => 
       { 
        opts.Items.Add("AnotherDependency", new AnotherDependency { Foo = "bar" }); 
        opts.Items.Add("flag1", someFlag); 
        opts.Items.Add("flag2", anotherFlag); 
       }) 
      }; 

      foreach (var obj in vm.Objects) 
      { 
       Console.WriteLine($"[{obj.Property1}, {obj.Property2}, {obj.Property3}, {obj.Property4}, {obj.Property5}, {obj.Property6}]"); 
      } 
     } 
    } 

    public class CustomConverter : ITypeConverter<SourceObject, DestinationObject> 
    { 
     public DestinationObject Convert(ResolutionContext context) 
     { 
      return Convert(context.SourceValue as SourceObject, context); 
     } 

     public DestinationObject Convert(SourceObject source, ResolutionContext context) 
     { 
      var dest = new DestinationObject 
      { 
       Property1 = source?.Property1, 
       Property2 = source?.Property2, 
       Property3 = source?.Property3 
      }; 

      var items = context.Options.Items; 

      Utility.SetupProperties(dest, 
       items["AnotherDependency"] as AnotherDependency, 
       dest.Property3, 
       items["flag1"] as bool? ?? false, 
       items["flag2"] as bool? ?? false); 

      return dest; 
     } 
    } 

    public static class Utility 
    { 
     public static void SetupProperties(DestinationObject x, AnotherDependency ad, string a, bool b, bool c) 
     { 
      x.Property4 = ad.Foo; 
      if (b || c) 
      { 
       x.Property5 = ad?.ToString() ?? a; 
      } 
      if (b && c) 
      { 
       x.Property6 = ad?.ToString() ?? a; 
      } 
      return; 
     } 
    } 
    public class ViewModel 
    { 
     public IEnumerable<DestinationObject> Objects { get; set; } 
    } 
    public class AnotherDependency { public string Foo { get; set; } } 
    public class SourceObject 
    { 
     public string Property1 { get; set; } 
     public string Property2 { get; set; } 
     public string Property3 { get; set; } 
    } 
    public class DestinationObject 
    { 
     public string Property1 { get; set; } 
     public string Property2 { get; set; } 
     public string Property3 { get; set; } 
     public string Property4 { get; set; } 
     public string Property5 { get; set; } 
     public string Property6 { get; set; } 
    } 
} 
+0

感谢您抽出时间。我一定会给这个尝试并回复/接受!再次感谢! – Will

+0

嘿,威尔,幸运吗?有什么我错过了吗? – AGB

+0

对不起,但我还没有机会尝试一下。我一定会回来后,我这样做。再次感谢! – Will