构建插件式的应用程序框架(三)----动态加载(ZT)

本文介绍了一种基于.NET平台的动态加载插件机制,详细解释了如何使用Assembly类的Load方法来加载DLL,并通过反射机制获取插件实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不管你采用什么方式实现插件式的应用程序框架,核心还是动态加载,换句话说,没有动态加载技术也就无所谓插件式的应用程序框架了。使用 Com 实现的话,你可以利用 Com 的 API 通过 ProgID 来动态创建 COM 对象,如果使用普通 DLL ,你需要使用 Windows 的 API 函数 LoadLibrary 来动态加载 DLL ,并用 GetProcAddress 函数来获取函数的地址。而使用 .NET 技术的话,你需要使用 Assembly 类的几个静态的 Load ( Load , LoadFile , LoadFrom )方法来动态加载汇集。
       一个 Assembly 里可以包含多个类型,由此可知,一个 Assembly 里也可以包含多个插件,就像前一篇文章所讲,只要它从 IPlugin 接口派生出来的类型,我们就承认它是一个插件类型。那么 Assembly 被动态加载了以后,我们如何获取 Assembly 里包含的插件实例呢?这就要用到反射( Reflection )机制了。我们需要使用 Assembly 的 GetTypes 静态方法来得到 Assembly 里所包含的所有的类型,然后遍历所有的类型并判断每一个类型是不是从 IPlugin 接口派生出来的,如果是,我们就使用 Activator 的静态方法 CreateInstance 方法来获得这个插件的实例。 .NET 的动态加载就是这几个步骤。下来,我做一个简单的例子来演练一下动态加载。首先声明一点,这个例子非常简单,纯粹是为了演练动态加载,我们的真正的插件式的应用程序框架里会有专门的 PluginService 来负责插件的加载,卸载。 
      我们的插件位于一个 DLL 里,所以我们首先创建一个 Class library 工程。创建一个 FirstPlugin 类让它派生于 IPlugin 接口,并实现接口的方法和属性,由于本文的目的是演示动态加载,所以 IPlugin 接口的 Loading 事件我们就不提供默认的实现了,虽然编译的时候会给出一个警告,我们不必理会它。这个插件的功能就是在应用程序里创建一个停靠在主窗体底部的 ToolStrip ,这个 ToolStrip 上有一个按钮,点击这个按钮,会弹出一个 MessageBox 显示“ The first plugin ”。下面是代码:
   
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
using  PluginFramework;
None.gif
using  System.Windows.Forms;
None.gif
None.gif
namespace  FirstPlugin
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public class FirstPlugin:IPlugin
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private IApplication application = null;
InBlock.gif        
private String name="";
InBlock.gif        
private String description = "";
InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
IPlugin Members#region IPlugin Members
InBlock.gif
InBlock.gif        
public IApplication Application
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return application;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                application 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return name;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                name 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public string Description
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return description;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                description 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void Load()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (application != null && application.BottomToolPanel != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//创建一个向主程序添加的ToolStrip
InBlock.gif
                ToolStrip sampleToolStrip = new ToolStrip();
InBlock.gif                ToolStripButton button 
= new ToolStripButton("Click Me");
InBlock.gif                button.Click 
+= new EventHandler(button_Click);
InBlock.gif                sampleToolStrip.Items.Add(button);
InBlock.gif
InBlock.gif                
//在主程序的底端添加ToolStrip
InBlock.gif
                application.BottomToolPanel.Controls.Add(sampleToolStrip);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
void button_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            MessageBox.Show(
"The first plugin");
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
//相关的文章主要讲动态加载,所以卸载就不实现了
InBlock.gif
        public void UnLoad()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
throw new Exception("The method or operation is not implemented.");
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public event EventHandler<EventArgs> Loading;
InBlock.gif
ExpandedSubBlockEnd.gif        
#endregion

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

      接下来我们创建一个Windows Application工程让主窗体派生于IApplication接口并实现IApplication接口的方法和属性,下来我们声明1个MenuStrip和1个StatusStrip,让他们分别停靠在窗口的顶部和底端,接下来我们声明4个ToolStripPanel,分别人他们停靠在上下左右四个边,最后我们创建一个ToolStrip,在上边添加一个按钮,当点击这个按钮的时候,我们动态的加载插件。
      为了方便演示,我们把生成的Assembly放置到固定的位置,以方便主程序加载,在本例里,我们在应用程序所在的文件夹里创建一个子文件夹Plugins(E:\Practise\PluginSample\PluginSample\bin\Debug\Plugins),将插件工程产生的Assembly(FirstPlugin.dll)放置在这个子文件夹。下面是动态加载的代码:      

None.gif private   void  toolStripButton1_Click( object  sender, EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
//动态加载插件,为了方便起见,我直接给出插件所在的位置
InBlock.gif
            String pluginFilePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\plugins\\FirstPlugin.dll";
InBlock.gif            Assembly assembly 
= Assembly.LoadFile(pluginFilePath);
InBlock.gif
InBlock.gif            
//得到Assembly中的所有类型
InBlock.gif
            Type[] types = assembly.GetTypes();
InBlock.gif
InBlock.gif            
//遍历所有的类型,找到插件类型,并创建插件实例并加载
InBlock.gif
            foreach (Type type in types)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (type.GetInterface("IPlugin"!= null)//判断类型是否派生自IPlugin接口
ExpandedSubBlockStart.gifContractedSubBlock.gif
                dot.gif{
InBlock.gif                    IPlugin plugin 
= (IPlugin)Activator.CreateInstance(type);//创建插件实例
InBlock.gif
                    plugin.Application = this;
InBlock.gif                    plugin.Load();
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedBlockEnd.gif        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值