2015-11-18 84 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

相关问题