2016-02-16 59 views
2

我正在使用他們的SDK與Quickbooks Desktop進行整合。我想建立一個通用的物品清單。他們的一般頂級項目查詢會返回所有項目(類型爲IORItemRet),然後在頂級項目中有不同的項目子類型。這些子類型不會繼承基類的Item類,所以我必須查看每個返回的項目,使用switch語句來確定它的類型,然後將該特定類型的屬性映射到我的通用Qu​​ickbooksItem類。如何幹掉這段代碼

正如您在下面看到的,代碼是相當多餘的。我希望能夠封裝ListID和Name的公共屬性類型設置,如果可能的話。

任何想法幹這個代碼?我想至少我可以創建一個函數,接受(ref qbItem, string ListId, string Name)並在每個case中調用它......但仍然非常潮溼......我希望有一些DRYer。

public static QuickbooksItem ConvertQueryResponseToClass(IORItemRet itemRet) 
{ 
    var itemType = itemRet.ortype; 
    var typeTest = itemRet.Type; 

    QuickbooksItem qbItem = new QuickbooksItem(); 

    switch (itemType) 
    { 
     case ENORItemRet.orirItemServiceRet: 
      var itemService = itemRet.ItemServiceRet as IItemServiceRet; 
      qbItem.Id = itemService.ListID.GetValue(); 
      qbItem.Name = itemService.Name.GetValue(); 
      qbItem.ItemType = ItemTypes.Service; 
      break; 

     case ENORItemRet.orirItemInventoryRet: 
      var itemInventory = itemRet.ItemInventoryRet as IItemInventoryRet; 
      qbItem.Id = itemInventory.ListID.GetValue(); 
      qbItem.Name = itemInventory.Name.GetValue(); 
      qbItem.ItemType = ItemTypes.Inventory; 
      break; 

     case ENORItemRet.orirItemNonInventoryRet: 
      var itemNonInventory = itemRet.ItemNonInventoryRet as IItemNonInventoryRet; 
      qbItem.Id = itemNonInventory.ListID.GetValue(); 
      qbItem.Name = itemNonInventory.Name.GetValue(); 
      qbItem.ItemType = ItemTypes.NonInventory; 
      break; 

     case ENORItemRet.orirItemOtherChargeRet: 
      var itemOtherCharge = itemRet.ItemOtherChargeRet as IItemOtherChargeRet; 
      qbItem.Id = itemOtherCharge.ListID.GetValue(); 
      qbItem.Name = itemOtherCharge.Name.GetValue(); 
      qbItem.ItemType = ItemTypes.Other; 
      break; 

     case ENORItemRet.orirItemSalesTaxRet: 
      var itemSalesTax = itemRet.ItemSalesTaxRet as IItemSalesTaxRet; 
      qbItem.Id = itemSalesTax.ListID.GetValue(); 
      qbItem.Name = itemSalesTax.Name.GetValue(); 
      qbItem.ItemType = ItemTypes.SalesTax; 
      break; 

     case ENORItemRet.orirItemSalesTaxGroupRet: 
      var itemSalesTaxGroup = itemRet.ItemSalesTaxGroupRet as IItemSalesTaxGroupRet; 
      qbItem.Id = itemSalesTaxGroup.ListID.GetValue(); 
      qbItem.Name = itemSalesTaxGroup.Name.GetValue(); 
      qbItem.ItemType = ItemTypes.SalesTaxGroup; 
      break; 
    } 

    return qbItem; 
} 
+0

您*可能*能夠使用Reflection對所有類型的屬性進行相同操作。 – Dave

+0

http://stackoverflow.com/questions/5379730/using-reflection-to-call-a-method-of-a-property – Dave

+0

所以*所有*這些類型聲明和實現相同類型的成員具有相同的名稱( ListID,Name),但他們都是這樣做的,而不共享一個通用的基類? – Amit

回答

1

我沒有辦法測試,但這樣的事情應該工作:

var itemType = itemRet.ortype; 
var typeTest = itemRet.Type; 

QuickbooksItem qbItem = new QuickbooksItem(); 

PropertyInfo ListIdProperty = typeTest.GetProperty("ListID"); 
MethodInfo ListValueMethod = ListIdProperty.GetMethod("GetValue"); 

qbItem.Id = (int)ListValueMethod.Invoke(ListIdProperty.GetValue(itemRet, null), null); 
1

一個想法是使用一個lib像AutoMapper映射每種類型的QuickbooksItem類。

這樣你就不需要自己編寫反射代碼。

+1

我喜歡Automapper,但除非它最近發生了變化,否則他需要手動爲每種類型創建一個映射,所以它仍然不會非常乾燥。 – Dave

+0

是的,但我相信將配置文件映射到配置文件使代碼更清潔 –

+0

您可以創建地圖,只要屬性名稱匹配,它會自動映射它們,而不必單獨指定它們 –