2016-06-01 38 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