首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

NBearV3 教程——MVP(Model/View/Presenter)模式實作

     編輯:關於.NET

版本資訊

版本:1.1 [2007-02-12]

簡介

本教程基於《NBearV3 Step by Step 教程——IoC 篇》,示範如何利用 NBearV3 的 MVP 模組實作基於 IoC 的 MVP 模式。您將看到,封裝了 NBear IoC 模組的 NBear.MVP 不僅大幅增強表現層可測試性,更能充分利用既有 IoC 模組獲得依賴注入能力與分散式服務支援。

註:建議先閱讀 IoC 篇教程以掌握 ORM 與 IoC 基礎知識。

學習目標

透過本教程,讀者應能全面掌握使用 NBearV3 MVP 模組實作表現層 MVP 模式。

程式碼範例來源

教程所有專案與代碼收錄於 NBearV3 最新原始碼套件(nbear.org 下載)中的 tutorials\MVP_Tutorial 目錄。

預估時間

不超過 45 分鐘。


Step 1:下載 NBearV3 並準備環境

  1. 訪問 https://nbear.org 下載最新版本至本地目錄。
  2. 解壓至 C:\,將看到 dist、doc、cases、src、tutorials 等目錄。本教程使用 dist 目錄下的 release 版 DLL 與 tutorials 中的 IoC 基礎教程。
  3. 將 tutorials 中的整個 IoC_Tutorial 目錄複製至任意位置並重命名為 MVP_Tutorial,以 IoC 教程為基礎進行擴充。

Step 2:定義 View 與 Presenter

MVP 模式包含 Model、View、Presenter 三部分。在 NBear.MVP 中,Model 直接使用基於 NBear.IoC 的 Service,故僅需額外定義 View 與 Presenter 代碼。為充分解耦 M、V、P,將運用介面、泛型與 IoC 技術。

2.1 新增 ViewInterfaces 類庫專案

加入參考 dist\NBear.Common.dll 與 Entities 專案。新增 ISampleView.cs:

using System;
using Entities;

namespace ViewInterfaces
{
    public interface ISampleView
    {
        int CategoryID { get; }
        Category[] Categories { set; }
        Product[] ProductsInCategory { set; }
    }
}

2.2 新增 PresenterInterfaces 類庫專案

加入參考 dist\NBear.Common.dll、NBear.MVP.dll 與 Entities 專案。新增 ISamplePresenter.cs:

using System;
using Entities;
using NBear.MVP;

namespace PresenterInterfaces
{
    public interface ISamplePresenter : IPresenter
    {
        void GetCategories();
        void GetProductsInCategory();
    }
}

2.3 新增 PresenterImpls 類庫專案

加入參考 dist\NBear.Common.dll、NBear.IoC.dll、NBear.MVP.dll、ServiceInterfaces、ViewInterfaces、PresenterInterfaces、Entities 專案。新增 SamplePresenter.cs 實作 ISamplePresenter:

using System;
using System.Collections.Generic;
using Entities;
using ServiceInterfaces;
using PresenterInterfaces;
using ViewInterfaces;
using NBear.MVP;

namespace PresenterImpls
{
    public class SamplePresenter : Presenter<ISampleView, ICategoryService>, ISamplePresenter
    {
        #region ISamplePresenter Members

        public void GetCategories()
        {
            // Presenter 可做額外資料過濾,讓 Service 更可重用
            List<Category> categoriesWithProducts = new List<Category>();
            foreach (Category item in model.GetAllCategories())
            {
                if (item.Products.Count > 0)
                {
                    categoriesWithProducts.Add(item);
                }
            }
            view.Categories = categoriesWithProducts.ToArray();

            if (categoriesWithProducts.Count > 0)
            {
                view.ProductsInCategory = model.GetCategoryByID(categoriesWithProducts[0].CategoryID).Products.ToArray();
            }
        }

        public void GetProductsInCategory()
        {
            view.ProductsInCategory = model.GetCategoryByID(view.CategoryID).Products.ToArray();
        }

        #endregion
    }
}

說明:SamplePresenter 繼承 NBear.MVP.Presenter<TView, TModel> 基類並實作 IPresenter。基類提供對 NBear.IoC 的封裝,衍生類可存取 view 與 model 兩個 protected 成員。PresenterImpls 可像 ServiceImpls 一樣獨立測試,這是 MVP 模式最大優勢。

Step 3:在網站中使用 View 與 Presenter

3.1 修改網站專案

刪除原有 Default.aspx 及代碼,加入參考 ViewInterfaces、PresenterInterfaces、PresenterImpls(實際只需將 DLL 複製到 bin 目錄)。為 Default.aspx 加入 DropDownList、Button、GridView 控制項:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml" >
<head runat="server">
  <title>Untitled Page</title>
</head>
<body>
  <form id="form1" runat="server">
    <div>
      Choose a Category:&nbsp;<asp:DropDownList ID="listCategories" runat="server" DataTextField="CategoryName" DataValueField="CategoryID"></asp:DropDownList>
      <asp:Button ID="btnLoad" runat="server" OnClick="btnLoad_Click" Text="Load Products in Selected Cateogry" /><br /><br />
      <asp:GridView ID="gridProducts" runat="server"></asp:GridView>
    </div>
  </form>
</body>
</html>

3.2 實作 ISampleView 介面

Default.aspx.cs:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Entities;
using ViewInterfaces;
using PresenterInterfaces;
using NBear.MVP;

public partial class _Default : System.Web.UI.Page, ISampleView
{
    private ISamplePresenter presenter;

    protected void Page_Load(object sender, EventArgs e)
    {
        presenter = PresenterFactory.Create().GetPresenter<ISamplePresenter>(this);
        if (!IsPostBack)
        {
            presenter.GetCategories();
            DataBind();
        }
    }

    protected void btnLoad_Click(object sender, EventArgs e)
    {
        presenter.GetProductsInCategory();
        gridProducts.DataBind();
    }

    #region ISampleView Members

    public int CategoryID
    {
        get
        {
            if (listCategories.SelectedIndex < 0) return -1;
            return int.Parse(listCategories.Items[listCategories.SelectedIndex].Value);
        }
    }

    public Category[] Categories
    {
        set { listCategories.DataSource = value; }
    }

    public Product[] ProductsInCategory
    {
        set { gridProducts.DataSource = value; }
    }

    #endregion
}

關鍵點:

  • PresenterFactory.Create().GetPresenter<T>(view) 透過 NBear.IoC.ServiceFactory 取得 Presenter 實作,支援分散式 IoC。
  • 網站僅依賴 PresenterInterfaces,具體實作透過 IoC 依賴注入取得,修改設定檔即可切換實作無需重新編譯。
  • Presenter 透過 IPresenter.TypeOfModel 從 IoC 容器自動取得 Model(ServiceFactory.GetService<type>()),自動具備分散式能力。

3.3 修改 Web.config

在 castle 設定區段中新增 Presenter 元件註冊:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="entityConfig" type="NBear.Common.EntityConfigurationSection, NBear.Common"/>
    <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
  </configSections>
  <entityConfig>
    <includes>
      <add key="Sample Entity Config" value="~/EntityConfig.xml"/>
    </includes>
  </entityConfig>
  <castle>
    <components>
      <component id="category service" service="ServiceInterfaces.ICategoryService, ServiceInterfaces" type="ServiceImpls.CategoryService, ServiceImpls"/>
      <component id="sample presenter" service="PresenterInterfaces.ISamplePresenter, PresenterInterfaces" type="PresenterImpls.SamplePresenter, PresenterImpls"/>
    </components>
  </castle>
  <connectionStrings>
    <add name="Northwind" connectionString="Server=(local);Database=Northwind;Uid=sa;Pwd=sa" providerName="NBear.Data.SqlServer.SqlDbProvider"/>
  </connectionStrings>
  <system.web>...</system.web>
</configuration>

3.4 執行測試

執行網站瀏覽 Default.aspx,即可看到功能。改變分類選擇並點擊按鈕即可查看不同分類下的產品。


後記:Presenter 如何使用多個 Model?

實務上常遇到一個 Presenter 需存取多個 Model 的情況,有兩種做法:

  1. 繼承多 Model 泛型參數的基類:如 Presenter<IView, IModel1, IModel2>、Presenter<IView, IModel1, IModel2, IModel3> 等。使用與配置方式與前文相同。
  2. 繼承無 Model 的 Presenter<IView> 基類:需要用到任意 Model 時,直接呼叫 NBear.IoC.Service.ServiceFactory.Create().GetService<IServiceType>() 取得 Service 實例。此法更靈活,為推薦做法。

正文結束

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved