快捷搜索:

Enterprise Library深入解析与灵活应用(3):倘若将U

本文示例源代码或素材下载

近来在做一个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也一并整合进来。

一、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);

}

}

}

在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);

}

}

}

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();

this.Presenter.View = this;

}

}

}

在buttonCalculate_Click中,根本就不必要try/catch了,在View初始化时,直接经由过程UnityContainer的Resolve措施创建Presenter。

此中第一部分是exceptionHandling的设置设置设备摆设摆设,为了简单起见,我创建了一个自定义的ExceptionHandler:MessageBoxHandler来处置惩罚所有的exception,该handler仅仅将error message经由过程MessageBox显示出来,有兴趣的同伙可以下载source code看看。

第二部分是unity的设置设置设备摆设摆设,在中定义了ICalculator和Calculator的mapping关系,实现了Presenter和Calculator的解耦;而extensions的设置设置设备摆设摆设实现了Policy Injection和Unity的集成,具体实现可以查看本系列第一章。

这就使所有的实现。若何运算呈现非常,比如将第二个操作数设为零,我们定义的MessageBoxHandler就会被履行,并经由过程MessageBox将Message显示出来,就像这样:

P.S. 虽然讲Policy Injection利用到Presenter可以经由过程AOP的要领来进行非常的处置惩罚,然则这要求View上的所有具有潜在非常抛出的逻辑都必要经由过程Presenter来实现,由于ExceptionHandler是利用到Presenter上面的。

您可能还会对下面的文章感兴趣: