一個自定義MVP .net框架 AngelFrame


摘要:本篇是本人在完成.net平台下一個項目,對於MVP框架引發的一些思考,以及開發了一個小型的配置型框架,名字叫作AngelFrame。這個項目屬於前端桌面管理系統的一部分,最終要集成進去

關鍵詞:      .net,Framwork,MVP,框架,c#

前提:          當前有很多成熟的.net Plugin Framework,如MEF、SCSF、Sharpdevelop和OSGi.net等,它們在功能上各有特色。
需求:           1、開發的項目或者說模塊屬於一個大系統的一部分,它需要最終集成於大系統中,比如一個大系統的用戶管理功能模塊。
                    2、大系統采用的框架.net Plugin Framework並不確定,有可能是SCSF,也有可能是MEF。因此此模塊不推薦使用任何大型框架(代碼、實例化過程不可控)。
                    3、然而不采用任何的框架會導致,寫出來的看起來很混亂,界面與邏輯雜堆在一起,smelly,與我們的審美情調格格不入。
說明:          這時一個適用的框架可以幫大忙。
                  只需在項目中引用Framework.dll、Microsoft.Practices.CompositeUI.dll、Microsoft.Practices.ObjectBuilder.dll, 就可以在項目中迅速部署MVP模式,發布並且訂制事件,從而 徹底實現解耦。
                  在后期集成到大系統中的過程中,使用也極為方便。
 

1、MVP的具體實現

       使用MVP的目的是為了實現類之間的松耦合,其中SCSF提供了完善的實現機制。有時因為項目要求不使用SCSF框架,而拋卻MVP帶來的代碼整潔性、松耦合性實屬不該。故編寫適合自己使用的,用來實現MVP模式的框架是有必要的。

       這里介紹框架AngelFrame及其使用方法,它功能小巧,易於擴展,使用方便。下圖是MVP的具體實現、使用的結構圖,它包含了Model、View、IView、Presenter以及EventPublication和EventSubscription。


 

 

2、AngelFrame的使用示例

      下面是一個小例子,它使用AngelFrame框架,按照如下的代碼編輯,可以實現界面快速訂制。

​下面的Form1是我們將要實現的主界面。它分成左右兩區,分別命名為UC1,UC2。其中UC1又分成左右兩區,其中右區命名為UC3。點擊UC1上的按鈕,可以彈出一個對話框。在松耦合的情況下,UC1、UC2、UC3的實例均可被靈活替換成其它實例,只要它們實現相同的接口IUC1、IUC2、IUC3即可。

 

2.1   Form1的實現代碼片段

1
2
3
4
5
6
public interface IForm1
{
         void ShowDialog();
         IUC1 UC1 { set ; }
         IUC2 UC2 { set ; }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public partial class Form1 : Form, IForm1
{
         private IUC1 _uc1;
         public IUC1 UC1
         {
             set
             {
                 _uc1 = value;
                 ((Control)_uc1).Dock = DockStyle.Fill;
                 panelEx1.Controls.Add((Control)_uc1);
             }
         }
 
         private IUC2 _uc2;
         public IUC2 UC2
         {
             set
             {
                 _uc2 = value;
                 ((Control)_uc2).Dock = DockStyle.Fill;
                 panelEx2.Controls.Add((Control)_uc2);
             }
         }
 
         public new void ShowDialog()
         {
             base .ShowDialog();
             // MessageBox.Show("hello , i am view1.form1 !");
         }
}

          代碼說明:在panelEx1上添加UC1,在panelEx2上添加UC2;這里的實例化及實例賦值都由AngelFrame管理,采用依賴注入IOC設計模式。

2.2   UC1的實現代碼片段

1
2
3
4
5
6
7
public interface IUC1
{
         void ShowDialog1();
         IUC3 UC3 { set ; }
         [EventPublication( "U" , PublicationScope.Global)]
         event EventHandler AfterClickButton;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public partial class UC1 : UserControl, IUC1
{
         private IUC3 _uc3;
         public IUC3 UC3
         {
             set
             {
                   _uc3 = value;
                   ((Control)_uc3).Dock = DockStyle.Fill;
                   panelEx1.Controls.Add((Control)_uc3);
             }
         }
 
         public void ShowDialog1()
         {
             MessageBox.Show(“I am view1.uc1 ! ");
         }
 
         [EventPublication( "TestEvent" , PublicationScope.Global)]
         public event EventHandler AfterClickButton;
         private void buttonX1_Click( object sender, System.EventArgs e)
         {
             if (AfterClickButton != null )
                 AfterClickButton( this , e);
         }
1
2
3
4
5
6
7
8
public class PUC1 : MPresenter<IUC1>
{
        [EventSubscription( "TestEvent" , ThreadOption.UserInterface)]
         private void OnAfterClickButton( object sender, EventArgs args)
         {
              View.ShowDialog1();
         }
}

       代碼說明:可以看出在panelEx1上添加UC3,UC1中存在一個事件發生器,它只負責在點擊按鈕的時候拋出事件。這里,具體的事件捕獲代碼放在PUC1上,而它可以直接   訪問UC1,從而彈出對話框。

 

2.3  配置文件App.config代碼片段

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
< 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" />
       
          < object name = "thisIsPUC1" assembly = "View1.dll" className = "View1.Presenters.PUC1" >
              < property name = "View" refObject = "thisIsUC1" />
          </ object >
        </ objects >
        < contexts >
          < context refObject = "thisIsPUC1" />
        </ contexts >
   </ Framework >

       代碼說明:這是最重要的一環,所有的依賴注入IOC都是從這里開始的。在這里可以隨意的搭配界面,各個小模塊可以被靈活的替換,只要它們實現了同一個接口。

               

         從上圖中可以看出,兩者的UC3發生了替換,左側是一個日歷,右側是一個表盤,只要將上述的App.config代碼段中<object name="thisIsUC3" assembly="View3.dll" className="View3.UC3"/>改為<object name="thisIsUC3" assembly="View1.dll" className="View1.Views.UC3"/>即可達到這樣的效果。

  

3、總結

以上就是框架AngelFrame的使用方法、實現效果,AngelFrame雖小,但它提供了這些最基本最實用的開發模式,方便開發者專注於實現業務流程。

關於AngelFrame的具體實現可以參見代碼,如需其它功能,可以進行進一步擴展,如有需要代碼的可以直接留言或跟本人聯系,希望大家交流,完善AngelFrame。


 

 






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM