2015-11-18 131 views
1

我正在使用WCF服務,並且遇到了一些將我的實體映射到我的DTO的障礙。考慮以下使用反射投射IList <Interface>到列表<T>

namespace Foo.Entities 
{ 
     public class Order : IOrder 
     { 
      public string Name { get;set; } 
      public string Address { get;set; } 
      public IList<ILocation> Locations { get;set; } 
     } 
} 

namespace Foo.DTO 
{ 
     [DataContract] 
     public class Order 
     { 
      [DataMember] 
      public string Name { get;set; } 
      [DataMember] 
      public string Address { get;set; } 
      [DataMember] 
      public List<Location> Locations { get;set; } 
     } 
} 

這是非常簡單的:DTO.Order就是我從我的終點返回和Entities.Order是我使用的內部是什麼(我使用DI/IOC)的業務邏輯,數據操作等。由於我的業務層返回從實體命名空間中的類型,但終點從DTO的命名空間,我寫這將需要一個類型,其映射到另一種類型,像這樣小的映射方法返回類型:

public TTarget MapObject<TSource, TTarget>(TSource source, TTarget target) 
      where TSource : class 
      where TTarget : class 
     { 
      foreach (var prop in source.GetType().GetProperties()) 
      { 
       var targetProp = target.GetType().GetProperty(prop.Name, BindingFlags.Public | BindingFlags.Instance); 
       if(targetProp == null || !targetProp.CanWrite) continue; 

       if (prop.PropertyType.GetGenericTypeDefinition() == typeof (IList<>)) 
       { 
        ?? 
       } 
       else{ targetProp.SetValue(target, prop.GetValue(source)); } 
      } 

      return target; 
     } 

然後我就這樣調用這個方法:

factory.MapObject(Entities.DealerOrder, new GTO.DealerOrder()) 

其中Entities.DealerOrder表示包含數據的實例化對象。

一切工作正常,直到我到達IList類型的屬性,我在如何將IList轉換爲列表損失。我知道需要發生什麼,但迄今爲止我所閱讀的所有文件都沒有指出我正確的方向。

僞是

if (prop.PropertyType.GetGenericTypeDefinition() == typeof (IList<>)) 
{ 
    var lst = new List<type of targetProp>() 
    foreach(var val in prop.GetValue()) 
    { 
     var item = new Location() (I have to figure out this initialization based on the List type of targetProp. In this case it would be List<Location>) 
     var retval = MapObject(val, item); 
     lst.Add(retval); 
    } 
    targetProp.SetValue(target, lst); 
} 

我不知道如果我想要做的就是甚至有可能。我知道泛型和反射混合不好,所以如果有解決方案,它可能對我真正想要完成的事情過於複雜。如果情況變得更糟,我可以在每個DTO上放置一個靜態方法,它將接受源類型作爲參數並返回DTO的一個實例,但是我想避免必須手動將字段從實體映射到DTO如果可能的話。

任何幫助,非常感謝。

回答

2
  1. 您可以使用targetProp.GetGenericArguments()[0];來獲取要將您的收藏內容映射到的項目類型。
  2. 您可以使用Activator.CreateInstance創建List<T>而不是在編譯時在運行時已知T
  3. 您可以使用Activator.CreateInstance來創建要映射到的類型的實例。
  4. 調用MapObject時不能依賴類型推斷。您也需要通過反射來創建適當的通用方法,然後調用它。
  5. 你不能簡單地在列表上調用Add,因爲你不知道它是什麼樣的列表。您可以將它投射到ICollection並改爲撥打Add

難道你不能只使用像AutoMapper?那些人已經解決的問題,你爲什麼不使用他們的工作?

+0

我實際上並不熟悉AutoMapper,直到你說了些什麼。在從NuGet中拉出來之後,我在十分鐘內從字面上解決了這個問題。非常感謝! – dparsons

相關問題