2010-09-16 47 views
4

有沒有人知道一個很好的教程(C#首選)爲.NET 3.0或更高版本創建組件的分層對象模型,即充分利用泛型?組件對象模型教程?

  • 使用並暴露無限數量的包含對象;
  • 阻止客戶端應用程序直接實例化包含的對象;
  • 允許客戶端代碼使用'隧道'風格,例如

string columnName = db.Tables["Customers"].Columns["customer_number"].Name;

我發現這篇文章,Component Object-Model Recommendations但因爲它是用於Visual Studio .NET 2003,但我想有.NET 3.0中更好的方法。

謝謝。

UPDATE:

如果我理解正確索引...

db類,我可以用一個SortedList爲表容器和使用,索引來訪問返回Table實例。同樣,Table的索引器將訪問Column實例。因此,客戶端代碼看起來是這樣的:

string tableName = db["Customers"].Name;

的問題是,在db類公開除了TablesStoredProcsDBViews等)等收藏。所以我想我想保留每個集合類,將它們暴露爲屬性而不是使用索引器。這聽起來正確嗎?但是,我應該在這些集合類上使用索引器嗎?

回答

2
  • 允許客戶機代碼來使用 '隧道效應' 風格例如

    string columnName = db.Tables["Customers"].Columns["customer_number"].Name;

[...]我想保留集合類爲每個,把它們作爲屬性而不是使用索引。這聽起來正確嗎?

是的,這聽起來比索引器更好,因爲它可以提供更好的類型安全性。如果你公開一個普通的集合,它們每個都可以有自己的元素類型。使用索引器,您將被迫爲所有公開的集合選擇相同的集合類型。爲了說明這個事實:

public DataTable this[string tableName] { ... } 
//  ^^^^^^^^^ 
//  choose one, unspecific type for all exposed collections 

vs.

public IList<Customer> Customers { get { ... } } 
public IList<Supplier> Suppliers { get { ... } } 
//   ^^^^^^^^ 
//   the right type for each collection 

所以是的,確實顯示單個「類型」集合,而不是「無類型」集合集合。

旁註:你說你要允許隧道;有些人可能會告訴你,這違反了一些常用舉行OO原則,如單一職責原則(SRP),或關注(SoC)的分離。


  • 防止客戶端應用程序從直接實例包含的對象
public class Db 
{ 
    public IList<Customer> Customers { get { ... } } 
    ... 
} 

「包含的對象」可能意味着這裏兩件事情:

  • 有人可以代替你的整個Customers集合。你只需通過使屬性爲只讀來防止這種情況,即。只提供一個吸氣劑。

  • 有人可以在您的db.Customers集合中插入新的Customer。您可以通過選擇(只讀)集合類型Customers不允許插入防止這一點。

例如:與

private List<Customer> customers = new List<Customer>(); 
//^for class-internal use only 

public IList<Customer> Customers { get { return this.customers.AsReadOnly(); } } 
//               ^^^^^^^^^^^^^ 
//            expose collection as read-only 

  • 工作並暴露包含的對象的數目不定

這又可能意味着兩兩件事:

  • db公開收藏數沒有限制。顯然,當你希望每個集合都是專門輸入時,這是行不通的。當你所有的收藏品都暴露具有相同類型(例如,作爲DataTable S,或作爲非通用ICollection S)這隻作品,您需要提供一個索引。也就是說,您可以通過索引器公開的一個集合來訪問您的許多集合。

  • 您公開了一個衆所周知且數量有限的集合(例如CustomersSuppliers等)。然而,每個這些都可以包含儘可能多的子對象。當我編寫了我的答案的上述部分時,我假設了這種情況。當您進行隧道工程時,優勢在於更好的類型安全性和編譯時檢查。

關於最後一點:

db.Customers["John Smith"].BillingAddress 

db.Tables["Customers"].Rows["John Smith"].Columns["BillingAddress"] as Address 

在第一種情況中,編譯器可以檢查類型,如CustomersBillingAddress性質的,而在第二種情況,這些屬性被編碼爲字符串,編譯器不會注意到你是否有拼寫錯誤。另外,您必須使用類型轉換自己指出正確的數據類型。

1

閱讀使用C#語言中的索引器。這是一個relevant page

+0

我編輯了我的問題,希望澄清哪些索引器可能暗示或不暗示。謝謝。 – onedaywhen 2010-09-17 09:03:36

+0

是的,你明白了。沒有問題,你可以簡單地使用db.StoredProcs [「blah」],就像使用db.Tables []一樣。索引器位於StoredProcs集合中。自動如果您使用.NET集合類。 – 2010-09-17 09:20:36