2014-10-08 15 views
0

我知道,問題很長,可能很難理解,但希望有人點擊它,現在我可以更詳細地解釋我的問題。如何有效地設計創建/更新方法,需要創建/更新不同類型的屬性?

我有一個Create方法用於創建一個名爲'opportunity'的對象。一個機會有許多不同的屬性需要設置,但爲了簡單起見,我將使用'標題','位置'和'StartDate'。

我也有一個Update方法,它做了一些非常相似的事情,關於列出的屬性,它將以相同的方式設置它們。然而,作爲一個方面說明,我需要2個不同的方法,因爲它們有所不同。

這兩種方法都將另一個名爲'Entity'的對象作爲參數,用於設置'opportunity'的值。

所以,現在我的問題。我認爲最好的方法是使用1個方法來完成所有屬性設置,這兩種方法都使用該方法。我會傳遞一個元組列表給這個方法,它包含1)要設置的機會屬性名稱,以及2)要設置的實體屬性值。然而,要做到這一點,我想可能需要像字符串,對象這樣的元組,因爲實體屬性值可能是5種類型中的1種。據推測這會導致拳擊(因此是昂貴的)。除了這一點,我將使用的類型來決定如何更新給定的機會屬性,所以是這樣的:

if (PropType == typeof(string)) 
{ 
    //Do something 
} 
else if (PropType == typeof(Picklist)) 
{ 
    //Do something else 
} 
else if (PropType == typeof(DateTime)) 
{ 
    //Do something else 
} 

我的問題是,這是做的一個有效的方法?它背後的兩個主要原因是,它似乎有很多重複的代碼之間的創建方法和更新方法,以及在每個方法中的事情,如if(entity.prop.value!= null)opp.prop .value = entity.prop.value。第二個原因是這種方式更容易進行單元測試。我可以爲要設置的每個機會屬性創建一個測試,並將其作爲元組列表傳遞給我的新方法,並在正確創建/更新後返回。

我考慮了一個KeyValuePairs的列表,但我可能需要向列表中添加額外的信息位,所以用tuple去了。另外,我認爲元組傳遞給其他方法的成本較低(儘管分配成本更高)。

我敢肯定,儘管我盡了最大的努力,這仍然不清楚,所以有任何問題,請問。

編輯

爲了讓更多的清晰,已經有到位的更新方法(雖然我想重寫它的),有很多相同的代碼在其設定的機會屬性如下:

if(entity.Title.Value != null) opp.name = entity.Title.Value; 
else throw new Exception("Title not specified"); 

if(entity.Town.Value != null) opp.town = entity.Town.Value; 
else throw new Exception("Town not specified"); 

這是爲所有字符串屬性完成的。我現在的觀點是,我不認爲我應該需要複製這個對所有屬性,而是有一些,說:

//newOpp is passed in as the new opportunity 

//Fields refers to a tuple passed in as object, string 
//Item1 = entity field value 
//Item2 = newOpp property name 

PropertyInfo[] OppProps = newOpp.GetType().GetProperties(); 
PropertyInfo prop; 

foreach (var record in Fields) 
{ 
    prop = OppProps.FirstOrDefault(x => x.Name == record.Item2); 

    if(record.Item1 != null && prop != null) 
    { 
     Type PropType = prop.GetType(); 
     if (PropType == typeof(string)) 
     { 
      prop.SetValue(newOpp, record.Item1, null); 
     } 

     //Extend to include other types used e.g. DateTime etc. 
    } 
} 
+0

請您詳細說明SHORT嗎? – 2014-10-08 12:49:58

+0

@SHEKHARSHETE - 好吧,2種方法非常相似,不想重複代碼,並希望能夠輕鬆進行單元測試。在我的問題是我目前的想法和問題。這是做這件事的好方法嗎? – sr28 2014-10-08 12:52:42

+0

爲什麼不傳遞包含新值的dto/entity/poco,然後使用automapper將它們映射到Opportunity對象,或者使用方法手動映射它們到Opportunity對象? – Kristof 2014-10-08 12:55:07

回答

0

因爲代碼說更然後幾個註釋行,我做了一個例子來說明我的意思。

public class Opportunity 
    { 
     public string Title { get; set; } 
     public string Location { get; set; } 
     public DateTime StartDate { get; set; } 
    } 

    public class OpportunityDto 
    { 
     public string Title { get; set; } 
     public string Location { get; set; } 
     [IgnoreMap] 
     public DateTime StartDate { get; set; } 
    } 

    public class Saver 
    { 
     public void CreateOpportunity(OpportunityDto dto) 
     { 
      var newOpportunity = new Opportunity();//You'll need some database logic here 
      MapProperties(dto, newOpportunity); 
      //Add save/create logic 
     } 

     public void UpdateOpportunity(OpportunityDto dto) 
     { 
      var existingUpportunity = new Opportunity();//you'll need some database query logic here 
      MapProperties(dto, existingUpportunity); 
      //Add save/update logic 
     } 

     public void MapProperties(OpportunityDto dto, Opportunity target) 
     { 
      Mapper.CreateMap<OpportunityDto, Opportunity>() 
        .ForAllMembers(opt => opt.Condition(srs => !srs.IsSourceValueNull)); 
      Mapper.Map<OpportunityDto, Opportunity>(dto, target); 
      target.Startdate = dto.StartDate;//Insert more logic & mumbo jumbo here 
      //Or manually : 
      //target.Title = dto.Title; 
      //target.Location = dto.Location; 
      //target.StartDate = dto.StartDate; 
     } 
    } 
+0

這是我最初想到的那種事情,但提出了兩個問題。第一,這仍然包含許多代碼重複,因爲有許多相同類型的字段只是以相同的方式設置,例如, if(entity.property.value!= null)opp.property = entity.property.value。在你的例子中,我需要對每一個進行這種類型的空檢查。另外,一些實體字段並不總是映射到相同的機會字段。需要一些邏輯來確定哪些。 – sr28 2014-10-08 13:19:15

+0

所以如果我想清除標題,我只能將其設置爲空字符串,但從不更新爲空? – Kristof 2014-10-08 13:24:39

+0

@ sr28我更新了我的答案,以包含更多的自動映射功能。您可以使用ignoreMapping來表示您想要映射自己的字段(例如StartDate),並通過爲所有成員添加條件來跳過空屬性。我假設你可能有更多的需求,但automapper是爲了這個目的,所以我希望它可以滿足你的需要。 – Kristof 2014-10-08 13:32:44