组件对象模型教程?

时间:2010-09-16 15:36:32

标签: c# .net .net-3.5

有没有人知道为.NET 3.0或更高版本创建组件的分层对象模型的好教程(C#首选),即充分利用泛型?

  • 使用并暴露无限数量的包含对象;
  • 防止客户端应用程序直接实例化包含的对象;
  • 允许客户端代码使用“隧道”样式,例如

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

我发现这篇文章Component Object-Model Recommendations,但因为它适用于Visual Studio .NET 2003,但我认为.NET 3.0中有更好的方法。

感谢。

更新:

如果我正确理解了索引器......

db类中,我可以使用SortedList作为Table的容器,并使用和索引器来访问以返回Table实例。同样,Table的索引器将访问Column实例。所以客户端代码可能如下所示:

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

问题是,除了dbTablesStoredProcs等)之外,DBViews类还会公开其他集合。所以我想我想保留每个的集合类,将它们作为属性公开,而不是使用索引器。这听起来不错吗?我应该在这些集合类上使用索引器吗?

2 个答案:

答案 0 :(得分: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集合。您只需将属性设置为只读即可以防止这种情况发生。只提供一个吸气剂。

  • 有人可以在您的Customer集合中插入新的db.Customers。您可以通过选择不允许插入的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

VS

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

在第一种情况下,编译器可以检查属性的类型,例如CustomersBillingAddress,而在第二种情况下,这些属性被编码为字符串,编译器不会注意到如果你在那里有拼写错误。此外,您必须使用type-casts自己指出正确的数据类型。

答案 1 :(得分:1)

阅读使用C#语言的索引器。这是一个relevant page