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

自製輕量級 MVP.NET 框架 AngelFrame:解耦 UI 與邏輯、支援動態模組替換

     編輯:關於.NET

背景動機

  • 專案需整合至大型系統,但大系統採用的 Plugin Framework 不確定 (SCSF/MEF/其他)。
  • 引入重型框架導致程式碼不可控、部署複雜。
  • 完全無框架則 UI/邏輯耦合嚴重,維護困難。

需求:輕量、無外部強依賴、支援 MVP 模式、事件總線、依賴注入 (IOC)、模組動態替換。

AngelFrame 核心架構

包含:Model、View、IView、Presenter、EventPublication、EventSubscription。

MVP 結構圖

關鍵介面與基類

// 視圖介面
public interface IForm1 {
    void ShowDialog();
    IUC1 UC1 { set; }
    IUC2 UC2 { set; }
}

// Presenter 基類
public abstract class MPresenter<TView> where TView : class {
    protected TView View { get; private set; }
    public MPresenter(TView view) { View = view; }
}

// 事件發佈/訂閱屬性
[AttributeUsage(AttributeTargets.Event)]
public class EventPublicationAttribute : Attribute {
    public string Topic { get; }
    public PublicationScope Scope { get; }
    public EventPublicationAttribute(string topic, PublicationScope scope) { ... }
}

[AttributeUsage(AttributeTargets.Method)]
public class EventSubscriptionAttribute : Attribute {
    public string Topic { get; }
    public ThreadOption ThreadOption { get; }
    public EventSubscriptionAttribute(string topic, ThreadOption option) { ... }
}

實作範例:動態組合三層巢狀 UserControl

Form1 (主視圖)

public partial class Form1 : Form, IForm1 {
    private IUC1 _uc1; public IUC1 UC1 { set { _uc1 = value; AddToPanel(panelEx1, _uc1); } }
    private IUC2 _uc2; public IUC2 UC2 { set { _uc2 = value; AddToPanel(panelEx2, _uc2); } }
    public new void ShowDialog() { base.ShowDialog(); }
    private void AddToPanel(Panel p, IView v) { ((Control)v).Dock = DockStyle.Fill; p.Controls.Add((Control)v); }
}
Form1 設計時

UC1 (含巢狀 UC3、發佈事件)

public interface IUC1 {
    void ShowDialog1();
    IUC3 UC3 { set; }
    [EventPublication("TestEvent", PublicationScope.Global)]
    event EventHandler AfterClickButton;
}

public partial class UC1 : UserControl, IUC1 {
    private IUC3 _uc3; public IUC3 UC3 { set { _uc3 = value; AddToPanel(panelEx1, _uc3); } }
    public void ShowDialog1() { MessageBox.Show("I am UC1"); }
    public event EventHandler AfterClickButton;
    private void buttonX1_Click(object sender, EventArgs e) => AfterClickButton?.Invoke(this, e);
}

// Presenter 訂閱事件並操作 View
public class PUC1 : MPresenter<IUC1> {
    [EventSubscription("TestEvent", ThreadOption.UserInterface)]
    private void OnAfterClickButton(object sender, EventArgs args) => View.ShowDialog1();
}
UC1 設計時

IOC 配置檔 (App.config) — 核心解耦點

<Framework>
  <objects>
    <object name="Form1" assembly="View1.dll" className="View1.Views.Form1">
      <property name="UC1" refObject="thisIsUC1" />
      <property name="UC2" refObject="thisIsUC2" />
    </object>
    <object name="thisIsUC1" assembly="View1.dll" className="View1.Views.UC1">
      <property name="UC3" refObject="thisIsUC3" />
    </object>
    <object name="thisIsUC2" assembly="View1.dll" className="View1.Views.UC2" />
    <object name="thisIsUC3" assembly="View3.dll" className="View3.UC3" />  @* 可替換為 View1.Views.UC3 *@
    <object name="thisIsPUC1" assembly="View1.dll" className="View1.Presenters.PUC1">
      <property name="View" refObject="thisIsUC1" />
    </object>
  </objects>
  <contexts>
    <context refObject="thisIsPUC1" />
  </contexts>
</Framework>
UC3 為日曆 UC3 替換為表盤

動態替換展示

修改配置檔中 thisIsUC3 的 assembly 與 className,無需重新編譯主程式,即可將 UC3 從「日曆」替換為「表盤」或任何實作 IUC3 的元件。

總結

AngelFrame 僅需引用 Framework.dll、Microsoft.Practices.CompositeUI.dll、Microsoft.Practices.ObjectBuilder.dll,即提供:

  • 標準 MVP 模式實作
  • 屬性式事件總線 (發佈/訂閱解耦)
  • XML 配置驅動的 IOC 容器 (建構器模式)
  • 模組熱插拔能力 (修改配置即替換實作)

專注業務邏輯,輕鬆整合至任意大型系統。

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