Smart Client Software Factory 專案採用 MVP 模式。View 負責 UI 呈現,Model 關注業務,Presenter 協調兩者。原先在 View 事件中大量重複 try/catch 呼叫 ExceptionPolicy.HandleException,想透過 PIAB 以 AOP 方式統一異常處理,並整合 Unity 實現依賴注入。
View 持有 Presenter 參考,透過 Presenter 存取 Model;Presenter 持有 View 介面(IView)參考操作 UI,符合面向介面程式設計原則。

ICalculator:定義 DivideCalculator:實作介面CalculatePresenter:持有 ICalculator 與 ICalculateView,呼叫計算並顯示結果ICalculateView:定義 DisplayResultCalculateView:WinForm 實作介面,按鈕事件呼叫 Presenter,含 try/catch 處理異常目標:
[ExceptionCallHandler("UI Exception Policy")]
public class CalculatePresenter : MarshalByRefObject
{
[Dependency]
public ICalculator Calculator { get; set; }
public ICalculateView View { get; set; }
public void Calculate(int op1, int op2)
{
int result = this.Calculator.Divide(op1, op2);
this.View.DisplayResult(result);
}
}
MarshalByRefObject 以支援透明 Proxy 攔截[ExceptionCallHandler] 套用異常處理策略[Dependency] 標註屬性注入public partial class ViewBase : Form
{
private IUnityContainer _unityContainer;
protected IUnityContainer UnityContainer
{
get
{
if (_unityContainer == null)
{
_unityContainer = new UnityContainer();
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers.Default.Configure(_unityContainer);
}
return _unityContainer;
}
}
}
public partial class CalculateView : ViewBase, ICalculateView
{
public CalculatePresenter Presenter { get; set; }
private void buttonCalculate_Click(object sender, EventArgs e)
{
if (!int.TryParse(textBoxOp1.Text, out int op1) || !int.TryParse(textBoxOp2.Text, out int op2)) return;
this.Presenter.Calculate(op1, op2); // 無需 try/catch
}
private void CalculateView_Load(object sender, EventArgs e)
{
this.Presenter = this.UnityContainer.Resolve<CalculatePresenter>();
this.Presenter.View = this;
}
// DisplayResult 實作略
}
<exceptionHandling>
<exceptionPolicies>
<add name="UI Exception Policy">
<exceptionTypes>
<add type="System.Exception, mscorlib" postHandlingAction="None" name="Exception">
<exceptionHandlers>
<add type="Artech.UnityInMVP.ExceptionHandlers.MessageBoxHandler, Artech.UnityInMVP" name="Custom Handler" />
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionPolicies>
</exceptionHandling>
自訂 MessageBoxHandler 以 MessageBox 顯示錯誤訊息。
<unity>
<containers>
<container>
<types>
<type type="Artech.UnityInMVP.ICalculator, Artech.UnityInMVP" mapTo="Artech.UnityInMVP.Calculator, Artech.UnityInMVP" />
</types>
<extensions>
<add type="Artech.UnityInMVP.UnityExtensions.PolicyInjectionExtension, Artech.UnityInMVP" />
</extensions>
</container>
</containers>
</unity>
Extension 實現 PIAB 與 Unity 整合(詳見系列第一篇)。
除數為零時,MessageBox 顯示錯誤訊息。
註:此做法要求所有潛在異常邏輯均經由 Presenter 呼叫,因 Handler 掛在 Presenter 上。
完整原始碼可供下載參考。