【问题标题】:ASP.NET WebForms - Control design (w.r.t. data)ASP.NET WebForms - 控件设计(w.r.t. 数据)
【发布时间】:2011-03-28 00:24:07
【问题描述】:

我正在使用 WebForms 设计/构建一个中等规模的 ASP.NET Web 应用程序。该项目的主要工作是构建每个 Web 表单,我不知道如何设计(在代码/数据/数据流意义上)我的控件。

我会给你一些我正在处理的例子,以便你理解我的意思:


应用程序中的一个常见任务是输入和显示街道地址。所以我创建了一个名为“AddressFields”的用户控件,其中包含一系列 HtmlInputText 元素(一个用于第 1 行,另一个用于城镇/城市、国家/地区、邮政编码等)。我的 DB 实体类包含一个名为“Address”的类,因此该控件具有以下方法:

  • void ShowAddress(Address addr) - 用适当的文本填充 HtmlInputText 元素。
  • void UpdateAddress(Address addr) - 用 HtmlInputText 元素的当前内容更新 addr 的内容
  • Address CreateAddress() - 创建一个新的 Address 实例,然后将其传递给 UpdateAddress,然后返回它

到目前为止,一切都很好。这是因为 AddressFields 控件是“愚蠢的”,它所做的只是向用户显示和检索数据。 ViewState 也直接由 HtmlInputText 字段管理,因此不需要额外的逻辑。


我的应用程序中的另一个实体是“客户端”,它是一个具有地址属性的类,但这个类也有一些更复杂的方面。例如,客户有一系列可以分配的标签(我的应用程序中的“类别”)。在本例中,我设计了 ASP.NET CheckboxList 控件的子类。

我创建了另一个名为“ClientFields”的 UserControl,其中包含显示客户信息所需的所有字段(包括 AddressFields 控件),但它还包括我的 CheckboxList 子类,称为“CategoryList”。

这里的问题是需要将 CategoryList 控件提供给要显示的数据(但不是在回发时,因为它使用视图状态)。 在这种情况下,我的问题是:谁负责连接数据库并检索类别列表

是 CategoryList 控件吗? (如果是这样,它在控件生命周期中的哪个位置查询数据库?它不能在 Control.Load 中执行,因为它发生在 ClientFields 被填充之后。它发生在 ClientFields 本身中吗?(再次,然后在生命周期中的哪个位置会发生这种情况吗,因为 ClientFields 在 Page.Load 中调用了它的 ShowClient(Client c) 方法。另一种方法是从 ClientFields 公开 CategoryList,以便页面可以直接访问它,但这违反了良好的软件设计。

【问题讨论】:

  • ShowClient(Client c),您的客户端类是否已加载类别数据?由于客户端类包含客户端数据,我猜类别数据是它的一部分。
  • 我在实体类中使用 Linq-to-SQL,并且 Client/Category 关系是多对多的,因此 Client.Categories 的内容只是一个链接表。客户端类在点击表单时已预先填充,但其他类别(未选择)的列表不可用,除非您专门从数据库中获取它们。

标签: asp.net controls single-responsibility-principle


【解决方案1】:

在我看来,CategoryList 负责检索类别列表数据,因为无论特定客户是否选择了一个或多个类别数据,都应该检索所有类别数据。

CategoryList 在其生命周期内何时查询数据库?

一般来说,重写 OnInit 方法来填充 CategoryList,但此时 ViewState 不会开始工作,因此您必须从 DB 中检索数据并在每次回发时自行填充。如果您想依赖 ViewState,请在重写的 OnInit 方法上定义并注册 Page 的 InitComplete 事件处理程序,并在事件处理程序中填充 CategoryList。 OnInit 方法和 InitComplete 事件都在 Load 事件之前被调用/触发。

//In CategoryList control
protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
    Page.InitComplete += new EventHandler(Page_InitComplete);
}

void Page_InitComplete(object sender, EventArgs e)
{
    // retrieve the data and populate the control
}

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-03
    • 2011-11-06
    • 2011-07-22
    • 1970-01-01
    相关资源
    最近更新 更多