2010-03-30 19 views
2

我目前正在開發一些用戶控件,以便我可以在項目中的多個位置使用它們。一個控件是關於編輯客戶地址列表的。因爲這需要在項目中的幾個地方完成,所以我想讓它成爲一個簡單的用戶控件。用戶控件包含一箇中繼器控件。默認情況下,中繼器顯示一個要編輯的地址項目。如果需要添加更多的地址,用戶可以點擊一個按鈕來添加一個額外的地址進行輸入。用戶控件應該用於創建新地址以及編輯現有地址。 地址的業務實體看起來是這樣的:ASP.net用戶控件和商業實體

public class Address 
{ 
    public string Street { get; set; } 

    public City City { get; set; } 

    public Address(string street, City city) 
    { 
     Check.NotNullOrEmpty(street); 
     Check.NotNull(city); 

     Street = street; 
     City = city; 
    } 
} 

正如你可以看到,如果有一個街道,一個城市一個地址只能被實例化。

現在我的想法是用戶控件公開名爲Addresses的集合屬性。 此屬性的獲取器從中繼器收集地址並將其返回到集合中。 setter會將要編輯的地址數據綁定到中繼器。

像這樣:

public partial class AddressEditControl : System.Web.UI.UserControl 
{ 

    public IEnumerable<Address> Addresses 
    { 
     get 
     { 
      IList<Address> addresses = new List<Address>(); 
      // collect items from repeater and create addresses 
      foreach (RepeaterItem item in addressRepeater.Items) 
      { 
       // collect values from repeater item 

       addresses.Add(new Address(street, city)); 
      } 

      return addresses; 
     } 
     set 
     { 
      addressRepeater.DataSource = value; 
      addressRepeater.DataBind(); 
     } 
    } 
} 

首先,我很喜歡這種方法,因爲它是面向對象使得它很容易重新使用控制。但在我的項目中的某個地方,我想使用這個控件,這樣用戶可以輸入一些地址。我想預先填寫每個中繼器項目的街道輸入字段,因爲我有這些數據,所以用戶不需要全部通過他自己輸入。

現在的問題是,此用戶控件只接受地址處於有效狀態(因爲地址對象只有一個構造函數)。所以我不能這樣做:

IList<Addresses> addresses = new List<Address>(); 
addresses.Add(new Address("someStreet", null)); // i dont know the city yet (user has to find it out) 

addressControl.Addresses = addresses; 

所以上述是不可能的,因爲我會因爲城市爲空而得到地址錯誤。

現在我的問題:我將如何創建這樣的控制? ;) 我在考慮使用地址DTO而不是實際地址,所以稍後可以將它映射到一個地址。這樣我可以傳入和傳出一個地址集合,這些地址不需要是有效的。 還是我誤解了用戶控件的工作方式?有沒有最佳做法?

回答

3

將Business Objects(其中有嚴格的規則和受限制的構造函數)直接綁定到UserControls(可能必須允許處於部分和無效狀態的數據)充滿了危險。

如果您要使用地址視圖模型(視圖模型是用於在控制器和用戶控件之間進行對話的DTO),那麼您可以允許任何舊視圖模型中的垃圾,這些垃圾必須經過驗證在它變成一個地址之前。

這也允許從業務層分離View/UserControl,因此重用變得更容易。