C#实现插件框架--过程

来源:互联网 发布:知乎 女生喜欢内射 编辑:程序博客网 时间:2024/05/28 16:07

以下例子实现界面和数据操作的分离,界面成为一个dll,数据操作部分成为一个dll。

先上一个框图:

 

 

从上面的框图可以看出整体上需要:三个接口

下面是代码:

(1)建立第一个项目(以便形成dll),名称为:PluginKernel,此项目里面只需定义三个接口,为了层次分明,这三个接口分在两个.cs文件中。

先在IControl.cs(或IApp)文件中定义两个接口:

namespace CSPluginKernel

 {

      public interface IApplicationObject   //应用程序主界面接口

      {
          void SetDelegate( EventHandler target );   //传递一个委托,即函数指针作为形参,这个委托会保存在主界面对象的appEvent成员中

          IDocumentObject GetActivatedDocuments(); // 获取当前使用的文档对象
      }

      public interface IDocumentObject   //文档对象(文本框)接口

      {

          string SetText { get; set; }
          Color SelectionColor { get; set; }
          Font SelectionFont { get; set; }

      }

}

然后IPlugin.cs文件中定义一个插件接口:

namespace CSPluginKernel {

     public interface IPlugin

     {
          ConnectionResult Connect( IApplicationObject app );    //插件注册函数
          void OnDestory();
          void OnLoad();   //插件加载
          void Run();        //运行插件
     }

}

 

(2)建立第二个项目,名称为:MyPlugin1,此项目就包含一个具体插件类。

建立MyPlugin1.cs文件,在此文件中添加如下代码:

namespace MyPlugin1
{
    public class MyPlugin1 : IPlugin
    {
           //成员变量   

          private IApplicationObject _App;
          private IDocumentObject    _CurDoc;

 

         //函数

         public MyPlugin1() { }

         public ConnectionResult Connect( IApplicationObject app )  //注册,只用到_App

         {
                _App = app;      //注册时保存住主界面对象_App
                _App.SetDelegate(new EventHandler( this.ActiveDocumentChanged ) );  //注册时让主界面的事件appEvent保存住插件的函数指针
               return ConnectionResult.Connection_Success;  //返回连接成功字符串,通知注册成功
        }
        private void ActiveDocumentChanged( object sender , EventArgs e )

        {
              //比如在主界面调整了当前激活文本框,要通知给插件,使插件把数据显示在主界面当前激活的文本框中

              _CurDoc = _App.GetActivedDocument();   

        }

        public void Run()

        {
              //运算产生一些数据字符串“我的数据” ,具体代码略。  

              ...... 

              _CurDoc.SetText(”我的数据" );     //从而更新了数据并在主界面中显示

        }

        public void OnLoad()   //初始化工作,用到_CruDoc有关

        {
             _CurDoc = _App.GetActivedDocument();   //插件加载时,保存住当前激活的文本框,下面还可以对文本框做一些初始化工作,比如设置文本框背景色

             ......   //其它初始化工作
        }

        public void OnDestory() { }    //插件销毁的工作

 

   }  //类定义结束

} //命名空间结束

 

(3)建立第3个项目,名称为:App,此项目包含主界面

namespace App

{

      public class frmMain:System.Windows.Forms.Form ,CSPluginKernel.IApplicationObject

      {

             //成员变量

             private ArrayList plugins = new ArrayList();    //插件列表

             TextBox txtBox1;   //此TextBox继承与IDocumentObject接口,两个textbox只有一个是激活状态的

             TextBox txtBox2;   //此TextBox继承与IDocumentObject接口

             private EventHandler[] appEvent;  //事件数组,保存多个插件的函数指针,如果只有一个插件,就不需要数组了

 

             //函数

             private void LoadAllPlugins()  //加载所有插件

             {

                      Assembly tmp = Assembly.LoadFile( file );
                      Type[] types = tmp.GetTypes();

                      foreach( Type t in types )

                      {

                            plugins.Add( tmp.CreateInstance( t.FullName ) );     //用到反射技术,具体就不说了,省略了一些代码

                      }

                      foreach( IPlugin pi in plugins )  //注册并初始化每个插件

                      {
                              if( pi.Connect( (IApplicationObject)this ) == ConnectionResult.Connection_Success ) {
                              pi.OnLoad();   
                      }

             }

             private void RunPlugin(int index)   //运行插件,比如单击某个按钮,运行对应的插件

             {

                    ((IPlugin)plugins[index]).Run();    //省略了一些代码,具体选择哪个插件运行就不多说了

             }

             public void SetDelegate(EventHandler target )  //保存住插件中的函数指针

             {

                    this.appEvent[index]=target;   //具体index为多少就省略了,index也可以为插件名,则更方便

             }

             public IDocumentObject ChangeActivedDocument(int index)   //改变当前激活的文本框,比如单击某个按钮时发生

             {

                    this.appEvent[index]();   //通知对应的插件主界面更改了当前文本框,具体index为多少就省略了。

             }

             private void frmMain_Load(object sender, EventArgs e)     //界面显示时,加载所有插件

             {

                    this.LoadAllPlugins();

             }

 

      }

}

 

 

 

 

 

 

 

 

原创粉丝点击