2012-04-16 83 views
4

我試圖使用ValueInjector來壓扁一個類,並讓它也跨過從Nullable<int>'sint之間的值。使用ValueInjecter扁平化包括可空類型的對象

例如給出下面的(人爲)類:

class CustomerObject 
{ 
    public int CustomerID { get; set; } 
    public string CustomerName { get; set; } 
    public OrderObject OrderOne { get; set; } 
} 

class OrderObject 
{ 
    public int OrderID { get; set; } 
    public string OrderName { get; set; } 
} 

class CustomerDTO 
{ 
    public int? CustomerID { get; set; } 
    public string CustomerName { get; set; } 
    public int? OrderOneOrderID { get; set; } 
    public string OrderOneOrderName { get; set; } 
} 

我想拉平CustomerObject的實例來 一個CustomerDTO,它忽略了一個事實,即在客戶 和訂單ID的是不同類型的(一個是不可空的)。

所以我想這樣做:

CustomerObject co = new CustomerObject() { CustomerID = 1, CustomerName = "John Smith" }; 
co.OrderOne = new OrderObject() { OrderID = 2, OrderName = "test order" }; 

CustomerDTO customer = new CustomerDTO(); 
customer.InjectFrom<>(co); 

然後都填充屬性,具體是:

customer.CustomerID 
customer.OrderOneOrderID 
customer.OrderOneOrderName 

我知道我可以使用FlatLoopValueInjection拉平的對象,我正在使用這個NullableInjection類:

public class NullableInjection : ConventionInjection 
{ 
    protected override bool Match(ConventionInfo c) 
    { 
     return c.SourceProp.Name == c.TargetProp.Name && 
       (c.SourceProp.Type == c.TargetProp.Type 
       || c.SourceProp.Type == Nullable.GetUnderlyingType(c.TargetProp.Type) 
       || (Nullable.GetUnderlyingType(c.SourceProp.Type) == c.TargetProp.Type 
         && c.SourceProp.Value != null) 
       ); 
    } 

    protected override object SetValue(ConventionInfo c) 
    { 
     return c.SourceProp.Value; 
    } 
} 

基本上我想t o將兩者結合起來。這可能嗎?

回答

9

,你可以通過重寫TypesMatch方法做到這一點:

public class MyFlatInj : FlatLoopValueInjection 
    { 
     protected override bool TypesMatch(Type sourceType, Type targetType) 
     { 
      var snt = Nullable.GetUnderlyingType(sourceType); 
      var tnt = Nullable.GetUnderlyingType(targetType); 

      return sourceType == targetType 
        || sourceType == tnt 
        || targetType == snt 
        || snt == tnt; 
     } 
    } 

,或者從源代碼抓住FlatLoopValueInjection,當你需要編輯它(這是約10行)

+0

偉大工程CN!現在我唯一的問題是......你是怎麼解決這個問題的? – Rocklan 2012-04-19 23:08:29

+0

啊我看,你寫的東西:)偉大的工具!我用automapper我的最後一個項目,它被我逼瘋,ValueInjector看來很多simplier和更容易使用......如此偉大的工作:) – Rocklan 2012-04-19 23:40:52

+0

偉大的工作,男人戴的帽子 – 2013-10-15 12:11:31

-1
// !!! THIS IS FOR LoopInjection not FlatLoopValueInjection !!! 
public class NullableInjection : LoopInjection 
{ 
    public NullableInjection() : base() { } 

    public NullableInjection(string[] ignoredProps) : base(ignoredProps) { } 

    protected override bool MatchTypes(Type source, Type target) 
    { 
     // This is the most likely scenario test for it first. 
     bool result = source == target; 
     // if not a type match then lets do more expensive tests. 
     if (!result) 
     { 
      var snt = Nullable.GetUnderlyingType(source); 
      var tnt = Nullable.GetUnderlyingType(target); 

      // Make sure that underlying types have not reverted to null  
      // this will cause false positives. 
      result = ((source == target) 
        || ((tnt != null) && source == tnt) 
        || ((snt != null) && target == snt) 
        || ((tnt != null) && snt == tnt)); 
     } 
     return result; 
    } 
} 
+0

我對那名對象的屬性得到一個錯誤; tnt和snt都是空的並且匹配。這種情況下可能會導致不同的對象類型的分配,並引起異常(「System.ArgumentException」:其他信息:類型的對象「Namespace.A」不能被轉換爲類型「Namespace.B」)。 – Chewy 2016-02-04 11:47:25