日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Enterprise Library深入解析与灵活应用(3):倘若将Unity、PIAB、Exception Handling引入MVP模式.. .. .....

發布時間:2025/7/14 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Enterprise Library深入解析与灵活应用(3):倘若将Unity、PIAB、Exception Handling引入MVP模式.. .. ..... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近在做一個Smart Client Software Factory的項目。熟悉SCSF或者CAB的都應該很清楚MVP這種設計模式。MVP是MVC的一種變體,View和Mode分別關注于UI的呈現和業務模型,View和Mode完全分離,View通過Presenter實現對業務模型的訪問,Presenter“間接”地調用View實現對UI的操作。對于MVP中的異常處理,我們是直接通過Enterprise Library的Exception Handling Application Block來實現的。具體的做法是:在View中的每個控件的事件中添加try/catch block, 并在catch中通過ExceptionPolicy實現對異常的處理。這樣導致的問題是,相同的代碼重復散布于整個應用的各個角落,所以我又這樣的想法:通過Policy Injection以AOP的方式實現對異常的處理,當有了這個想法后,我又多想了一步,何不再將Unity也一并整合進來。(Source Code 下載)

一、MVP簡介

為了讓一些沒有接觸過MVP的讀者能夠理解后續的內容,我先對MVP做一個簡單的介紹。如下圖所示:MVP有點類似于我們熟悉的MVC, View負責實現對UI的呈現已經與用戶進行交互,在CAB中,View一般通過一個User Control來實現, Mode關注于具體的業務模型,獨立于View和Presenter。View具有一個Presenter的引用,當View需要調用Mode的時候(比如需要訪問Mode傳入查詢條件獲取數據),通過Presenter訪問Mode。對于Presenter來說,它需要對View進行操作(比如數據成功獲取后,將其顯示到View中),但是Presenter并不會“直接”對View本身進行引用,而是引用View的接口(IView),所以View對象是一個不穩定的對象,而Presenter僅僅需要View中一些固定的操作,所以對將這些操作定義在IView interface中,將對View的依賴轉化成對IView的依賴,這也充分體現了面向結構變成的原則。

二、模擬簡單的MVP

接下來我們通過一個簡單的場景來模擬MVP。這是我常用的計算器的例子,整體的構成如下圖所示:

1、ICalculator:Calculator的接口,定義了一個用于進行除法運算的操作

namespace Artech.UnityInMVP
{
??? public interface ICalculator
??? {
??????? int Divide(int op1, int op2);
??? }
}

2、Calculator:實現了ICalculator接口

namespace Artech.UnityInMVP
{
??? public class Calculator:ICalculator
??? {
??????? public? int Divide(int op1, int op2)
??????? {
??????????? return op1 / op2;
??????? }
??? }
}

3、CalculatePresenter:被View調用進行數學運算,并將運算結果顯示到View中

namespace Artech.UnityInMVP
{
???? public class CalculatePresenter
??? {
??????? public CalculatePresenter()
??????? {
?????????? this.Calculator = new Calculator();
??????? }

??????? public ICalculateView View
??????? { get; set; }

??????? public ICalculator Calculator
??????? { get; set; }

??????? public void Calculate(int op1, int op2)
??????? {
??????????? int result = this.Calculator.Divide(op1, op2);
??????????? this.View.DisplayResult(result);
??????? }
??? }
}

在CalculatePresenter具有一個ICalculateView 屬性,通過該屬性實現對于運算結果的顯示。之所以定義ICalculator 是想解除對具體的Calculator的依賴,但是到目前為止,這個目標還沒有達到,因為在構造函數中還是依賴于Calculator。

4、ICalculateView :定義了一個用于顯示運算結果的操作,該操作被CalculatePresenter調用

namespace Artech.UnityInMVP
{
?? public interface ICalculateView
??? {
??????? void DisplayResult(int result);
??? }
}

5、CalculateView:在本例中是一個Form,并實現了ICalculateView

namespace Artech.UnityInMVP
{
??? public partial class CalculateView : ICalculateView
??? {??????

??????? public CalculatePresenter Presenter
??????? { get; set; }

??????? #region ICalculateView Members

??????? public void DisplayResult(int result)
??????? {
??????????? this.textBoxResult.Text = result.ToString();
??????? }

??????? #endregion

??????? private void buttonCalculate_Click(object sender, EventArgs e)
??????? {
??????????? int op1;
??????????? int op2;
??????????? if(!int.TryParse(this.textBoxOp1.Text.Trim(), out op1))
??????????? {
??????????????? return;
??????????? }

???????????? if(!int.TryParse(this.textBoxOp2.Text.Trim(), out op2))
??????????? {
??????????????? return;
??????????? }

???????????? try
???????????? {
???????????????? this.Presenter.Calculate(op1, op2);
????????? ?? }
?????????? ? catch (Exception ex)
???????????? {
???????????????? if (ExceptionPolicy.HandleException(ex, "UI Exception Policy"))
???????????????? {
???????????????????? throw;
???????????????? }
???????????? }
??????? }

??????? private void CalculateView_Load(object sender, EventArgs e)
??????? {
??????????? this.Presenter = new CalculatePresenter ();
??????????? this.Presenter.View = this;
??????? }
??? }
}

在Load的時候對Presenter屬性進行初始化, 并將View對象設置為View本身。在buttonCalculate_Click中,傳入用戶輸入的操作數,并調用Presenter的Calculate方法。為了處理潛在的Exception,加了一個try/catch,并在catch中調用了Enterprise Library Excepton Handling Applicaion Block進行異常的處理。同時CalculateView 實現了ICalculateView的DisplayResult方法,將運算結果顯示在TextBox中。

三、通過Unity和Policy Injection對上面的程序進行改造

我現在的目標是對上面的設計進行改進,達到下述兩個目標:

  • 通過AOP的方式進行異常的處理,相同的try/catch頻繁出現不是一個好的現象(實際上在我們現在的項目中,除了惡異常處理,還有其他一些相識的非業務邏輯,我希望的是這些業務無關的邏輯都通過AOP實現)。
  • 解除CalculatePresenter 對Calculator的依賴,使其僅僅依賴于ICalculator。

我的思路是這樣的,將Policy Injection Application Block引入,用于實現Exception Handling操作;將Unity引入通過Depedency Injection實現對CalculatePresenter 和Calculator的解耦;同時通過Unity Extension實現Policy Injection和Unity的集成(參見本系列第一章).

為此我們先對CalculatePresenter進行改造。

namespace Artech.UnityInMVP
{
??? [ExceptionCallHandler("UI Exception Policy")]
??? public class CalculatePresenter:MarshalByRefObject
??? {
??????? public CalculatePresenter()
??????? {
??????????? this.Calculator = new Calculator();
??????? }

??????? public ICalculateView View
??????? { get; set; }

??????? [Dependency]
??????? public ICalculator Calculator
??????? { get; set; }

??????? public void Calculate(int op1, int op2)
??????? {
??????????? int result = this.Calculator.Divide(op1, op2);
??????????? this.View.DisplayResult(result);
??????? }
??? }
}

  • 為了讓Policy Injection能夠起作用,我讓其繼承MarshalByRefObject,并且以Custom Attribute的形式應用了ExceptionCallHandler,并制定exception handling policy(在真正的項目開發中,我推薦通過configuration的方式應用Policy injection)。
  • 通過[Dependency]實現了基于Unity的Property dependency.

然后我們接著對View進行改造,由于我們在CalculatePresenter使用了[Dependency][ExceptionCallHandler],我們需要通過Unity Container的方式來創建CalculatePresenter對象,為此我定義了View的基類:ViewBase.

namespace Artech.UnityInMVP
{
??? public partial class ViewBase : Form
??? {?????

??????? private IUnityContainer _unityContainer;

??????? protected IUnityContainer UnityContainer
??????? {
??????????? get
??????????? {
??????????????? if (this._unityContainer == null)
??????????????? {
??????????????????? this._unityContainer = new UnityContainer();
??????????????????? UnityConfigurationSection unityConfigSection = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
??????????????????? unityConfigSection.Containers.Default.Configure(this._unityContainer);
??????????????? }
??????????????? return this._unityContainer;
??????????? }
??????? }
??? }
}

在ViewBase 定義了IUnityContainer 屬性,用于View創建對應的Presenter對象,這樣CalculateView就可以這樣來定義了:

namespace Artech.UnityInMVP
{
??? public partial class CalculateView : ViewBase, ICalculateView
??? {
??????? public CalculateView()
??????? {
??????????? InitializeComponent();???????????????????
??????? }

??????? public CalculatePresenter Presenter
??????? { get; set; }

??????? #region ICalculateView Members

??????? public void DisplayResult(int result)
??????? {
??????????? this.textBoxResult.Text = result.ToString();
??????? }

??????? #endregion

??????? private void buttonCalculate_Click(object sender, EventArgs e)
??????? {
??????????? int op1;
??????????? int op2;
??????????? if(!int.TryParse(this.textBoxOp1.Text.Trim(), out op1))
??????????? {
??????????????? return;
??????????? }

???????????? if(!int.TryParse(this.textBoxOp2.Text.Trim(), out op2))
??????????? {
??????????????? return;
??????????? }

???????????? this.Presenter.Calculate(op1, op2);
??????? }

??????? private void CalculateView_Load(object sender, EventArgs e)
??????? {
??????????? this.Presenter = this.UnityContainer.Resolve<CalculatePresenter>();
??????????? this.Presenter.View = this;
??????? }
??? }
}

在buttonCalculate_Click中,根本就不需要try/catch了,在View初始化時,直接通過UnityContainer的Resolve方法創建Presenter。

我們最后來看看相關的配置:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
? <configSections>
??? <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
??? <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
? </configSections>
? <exceptionHandling>
??? <exceptionPolicies>
????? <add name="UI Exception Policy">
??????? <exceptionTypes>
????????? <add type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
??????????? postHandlingAction="None" name="Exception">
??????????? <exceptionHandlers>
????????????? <add type="Artech.UnityInMVP.ExceptionHandlers.MessageBoxHandler,Artech.UnityInMVP"
??????????????? name="Custom Handler" />
??????????? </exceptionHandlers>
????????? </add>
??????? </exceptionTypes>
????? </add>
??? </exceptionPolicies>
? </exceptionHandling>
? <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>
</configuration>

其中第一部分是exceptionHandling的配置,為了簡單起見,我創建了一個自定義的ExceptionHandler:MessageBoxHandler來處理所有的exception,該handler僅僅將error message通過MessageBox顯示出來,有興趣的朋友可以下載source code看看。

<exceptionHandling>
??? <exceptionPolicies>
????? <add name="UI Exception Policy">
??????? <exceptionTypes>
????????? <add type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
??????????? postHandlingAction="None" name="Exception">
??????????? <exceptionHandlers>
????????????? <add type="Artech.UnityInMVP.ExceptionHandlers.MessageBoxHandler,Artech.UnityInMVP"
??????????????? name="Custom Handler" />
??????????? </exceptionHandlers>
????????? </add>
??????? </exceptionTypes>
????? </add>
??? </exceptionPolicies>
? </exceptionHandling>

?

第二部分是unity的配置,在<types>中定義了ICalculator和Calculator的mapping關系,實現了Presenter和Calculator的解耦;而extensions的配置實現了Policy Injection和Unity的集成,詳細實現可以查看本系列第一章。
<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>
這就使所有的實現。如何運算出現異常,比如將第二個操作數設為零,我們定義的MessageBoxHandler就會被執行,并通過MessageBox將Message顯示出來,就像這樣:

?

P.S. 雖然講Policy Injection應用到Presenter可以通過AOP的方式來進行異常的處理,但是這要求View上的所有具有潛在異常拋出的邏輯都需要通過Presenter來實現,因為ExceptionHandler是應用到Presenter上面的。

轉載于:https://www.cnblogs.com/artech/archive/2008/08/22/1273753.html

總結

以上是生活随笔為你收集整理的Enterprise Library深入解析与灵活应用(3):倘若将Unity、PIAB、Exception Handling引入MVP模式.. .. .....的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 尤物在线视频观看 | 日韩久久影视 | 成人动漫在线免费观看 | 九九九视频在线观看 | 奇米激情| www天堂av| 日本三级午夜理伦三级三 | 色亭亭| aaaa毛片 | 国产高清视频在线免费观看 | 不卡在线播放 | 亚洲激情久久 | 影音先锋成人资源网站 | 深爱婷婷| 日本成人网址 | 中文字幕在线观看精品 | 久久性生活 | 久久sp| 精品久久蜜桃 | 在线观看免费视频一区二区 | 中文字幕无码乱码人妻日韩精品 | www一区 | 日本三级视频在线观看 | 国产人成一区二区三区影院 | 超碰人人澡 | 两口子交换真实刺激高潮 | 成人毛片视频免费看 | 国产成人一区二区三区免费看 | 国产综合久久久 | 热久久网站 | 艹久久| 欧美性高潮视频 | 制服丝袜在线看 | 日本a视频在线观看 | 伊人久久狼人 | 久久高清无码视频 | 色天堂视频 | 日韩一区二区三免费高清在线观看 | 丰满熟女人妻一区二区三 | 狠狠综合网 | 日本少妇裸体做爰 | 久久人妻少妇嫩草av无码专区 | 国产成人精品亚洲精品色欲 | 成人漫画网站 | 毛片视屏| 成人福利在线观看 | 成人在线免费观看视频 | 欧美黄色a级片 | 青草视频在线看 | www黄色com| 狂躁美女大bbbbbb黑人 | 久久丫丫 | 国产精品美女久久久久av爽 | 欧美色欧美色 | 用力挺进新婚白嫩少妇 | av女优天堂在线观看 | 老鸭窝久久| 国产肉丝在线 | 中国在线观看免费高清视频播放 | 狠狠干av| 日本三级久久久 | 国产婷婷久久 | 天堂在线视频免费观看 | 亚洲乱熟女一区二区 | 久久综合日本 | 日韩在线免费视频观看 | av一级久久 | 在线观看福利电影 | 精品久久一二三区 | 黄视频网站在线 | 欧美视频福利 | av在线毛片 | 一区二区三区视频在线观看 | 欧美成人一二三 | 性色av网站| 大奶毛片 | 91亚洲在线 | 国产免费无码一区二区视频 | 国产日韩av一区二区 | 99热r | 黄视频网站在线观看 | 欧美老熟妇乱大交xxxxx | 激情小说av | 日本人的性生活视频 | 在线观看jizz| 国产av精国产传媒 | 小向美奈子在线观看 | 日韩一区二区三区在线播放 | 久草新免费| 日批视频在线看 | 久久久久久毛片 | 国产原创精品 | 天天摸天天碰 | 久久久久久在线观看 | 落日余晖图片 | 欧美色频| 伊朗做爰xxxⅹ性视频 | 欧美片 | 97操碰 |