构建插件式的应用程序框架(五)-管理插件

 我们现在已经搭建了插件式的应用程序框架,接下来的工作就是要充实框架的内容,提供基本的服务,也就是Service。我想首要的任务就是提供插件的管理服务,我在前面的文章也提到了,要实现动态加载必须要知道插件寄宿在哪里,哪些要加载,哪些不加载,这些就是这篇文章要讨论的问题。

首先解决的就是插件放在什么地方,我采取的传统的方法,将插件放到应用程序所在目录下的制定目录,我会在应用程序所在的目录下创建一个文件夹,命名为Plugins。接下来的工作就是要通知哪些插件是要加载的,哪些是不需要加载的,我会将这些信息放到应用程序的配置文件中的制定配置块中,当应用程序运行的时候,就会读取配置文件,并根据获得的信息加载插件。另外我们的应用程序框架是建立在Service基础之上,所以我需要创建一个管理插件的service。

我们现在定义一个插件管理的Service接口。
using System;
using System.Collections.Generic;
using System.Text;

namespace PluginFramework
{
    public interface IPluginService
    {
        IApplication Application { get; set; }
        void AddPlugin(String pluginName, String pluginType, String Assembly, String pluginDescription);
        void RemovePlugin(String pluginName);
        String[] GetAllPluginNames();
        Boolean Contains(String pluginName);
        Boolean LoadPlugin(String pluginName);
        Boolean UnLoadPlugin(String pluginName);
        IPlugin GetPluginInstance(String pluginName);
        void LoadAllPlugin();
    }
}

PluginService要实现的目标首先是在配置文件中添加/删除要加载的插件以及相关的信息,接下来就是动态的加载插件。我们要定义几个类型:Plugin配置区块类型,Plugin元素类型,plugin元素集合类型,以便我们能够读取插件的信息。

最后我们实现PluginService:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Configuration;
using System.Reflection;
using System.Windows.Forms;
using System.IO;
using System.Collections;

namespace PluginFramework
{
    public class PluginService : IPluginService
    {
        private IApplication application = null;
        private PluginConfigurationSection config = null;
        private Dictionary<String, IPlugin> plugins = new Dictionary<string, IPlugin>();
        private XmlDocument doc = new XmlDocument();

        public PluginService()
        {

        }

        public PluginService(IApplication application)
        {
            this.application = application;

        }

        IPluginService Members#region IPluginService Members

        public void AddPlugin(string pluginName, string pluginType, string assembly, string pluginDescription)
        {
            doc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
            XmlNode pluginNode = doc.SelectSingleNode("/configuration/PluginSection");
            XmlElement ele = doc.CreateElement("add");
            XmlAttribute attr = doc.CreateAttribute("Name");
            attr.Value = pluginName;
            ele.SetAttributeNode(attr);
            XmlAttribute attrType = doc.CreateAttribute("Type");
            attrType.Value = pluginType;
            ele.SetAttributeNode(attrType);

            XmlAttribute attrAss = doc.CreateAttribute("Assembly");
            attrAss.Value = assembly;
            ele.SetAttributeNode(attrAss);

            XmlAttribute attrDes = doc.CreateAttribute("Description");
            attrDes.Value = pluginDescription;
            ele.SetAttributeNode(attrDes);
            pluginNode.AppendChild(ele);
            doc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
            ConfigurationManager.RefreshSection("PluginSection");
        }

        public void RemovePlugin(string pluginName)
        {
            doc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
            XmlNode node = doc.SelectSingleNode("/configuration/PluginSection");
            foreach (XmlNode n in node.ChildNodes)
            {
                if (n.Attributes != null)
                {
                    if (n.Attributes[0].Value == pluginName)
                    {
                        node.RemoveChild(n);
                    }
                }
            }
            doc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
            ConfigurationManager.RefreshSection("PluginSection");
        }

        public string[] GetAllPluginNames()
        {
            config = (PluginConfigurationSection)ConfigurationManager.GetSection("PluginSection");
            PluginConfigurationElement pe = new PluginConfigurationElement();
            ArrayList ps = new ArrayList();
            for (Int32 i = 0; i < config.PluginCollection.Count; i++)
            {
                pe = config.PluginCollection[i];
                ps.Add(pe.Name);
            }
            return (String[])ps.ToArray(typeof(String));
        }

        public bool Contains(string pluginName)
        {
            config = (PluginConfigurationSection)ConfigurationManager.GetSection("PluginSection");
            PluginConfigurationElement pe = new PluginConfigurationElement();
            List<String> ps = new List<string>();
            for (Int32 i = 0; i < config.PluginCollection.Count; i++)
            {
                pe = config.PluginCollection[i];
                ps.Add(pe.Name);
            }
            return ps.Contains(pluginName);
        }

        public bool LoadPlugin(string pluginName)
        {
            Boolean result = false;
            config = (PluginConfigurationSection)ConfigurationManager.GetSection("PluginSection");
            PluginConfigurationElement pe = new PluginConfigurationElement();

            String path = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + "\\Plugin";
            try
            {
                for (Int32 i = 0; i < config.PluginCollection.Count; i++)
                {
                    pe = config.PluginCollection[i];
                    if (pe.Name == pluginName)
                    {
                        Assembly assembly = Assembly.LoadFile(path + "\\" + pe.Assembly);
                        Type type = assembly.GetType(pe.Type);
                        IPlugin instance = (IPlugin)Activator.CreateInstance(type);
                        instance.Application = application;
                        instance.Load();
                        plugins[pluginName] = instance;
                        result = true;
                        break;
                    }
                }
                if (!result)
                {
                    MessageBox.Show("Not Found the Plugin");
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                result = false;
            }
            return result;
        }

        public bool UnLoadPlugin(string pluginName)
        {
            Boolean result = false;
            try
            {
                IPlugin plugin = GetPluginInstance(pluginName);
                plugin.UnLoad();
                result = true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
            return result;
        }

        public void LoadAllPlugin()
        {
            PluginConfigurationElement pe = new PluginConfigurationElement();
            config = (PluginConfigurationSection)ConfigurationManager.GetSection("PluginSection");
            String path = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + "\\Plugin";
            try
            {
                for (Int32 i = 0; i < config.PluginCollection.Count; i++)
                {
                    pe = config.PluginCollection[i];
                    Assembly assembly = Assembly.LoadFile(path + "\\" + pe.Assembly);
                    Type type = assembly.GetType(pe.Type);
                    IPlugin instance = (IPlugin)Activator.CreateInstance(type);
                    instance.Application = application;
                    instance.Load();
                    plugins[pe.Name] = instance;
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        public IApplication Application
        {
            get
            {
                return application;
            }
            set
            {
                application = value;
            }
        }

        public IPlugin GetPluginInstance(string pluginName)
        {
            IPlugin plugin = null;
            if (plugins.ContainsKey(pluginName))
            {
                plugin = plugins[pluginName];
            }
            return plugin;
        }

        #endregion
    }
}

由于代码比较多,我也就不一一列举了,只把比较重要的代码列出来,其余的我会提供源代码的下载。在实现了PluginService以后,我们需要有一个地方能够使用这个Service来管理插件,我的做法是在一个菜单里添加一个项目,当用户点击这个项目的时候弹出插件管理的对话框,用户在这个对话框中选择使用那些插件,当插件被选中的时候,插件会被立即加载进来,并且记录到配置文件里,当用户下次运行应用程序的时候,插件默认会被自动的加载。

另外从现在开始我们就需要使用配置文件了,所以,我们需要给应用程序添加一个app.config文件,文件内容如下:
xml.gif复制   Save.jpg保存
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section
          name="PluginSection"
          type="PluginFramework.PluginConfigurationSection, PluginFramework"
      />
    </configSections>
    <PluginSection>

    </PluginSection>
</configuration>
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="PluginSection" type="PluginFramework.PluginConfigurationSection, PluginFramework" /> </configSections> <PluginSection> </PluginSection> </configuration>

样子,总体来说我们就为Plugin的管理提供了一个基本的实现,如果大家还有什么不明白的地方,可以参考我提供的源代码或者通过e-mail和我联系。

源代码下载
http://files.cnblogs.com/guanjinke/pluginsample2.rar
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C 插件框架 demo 是一个用于展示 C 语言的插件框架示例。插件框架是一种允许用户在应用程序中动态加载和卸载插件的架构。这个 demo 展示了如何使用 C 语言来实现一个基本的插件系统。 首先,我们需要定义插件的接口,以便应用程序能够与插件进行交互。接口定义了插件所必须实现的函数和数据结构。接口中的函数可以是回调函数,用于应用程序调用插件中的功能。 然后,我们可以定义插件的结构体,其中包含插件的元数据和实现接口函数的函数指针。这些函数指针将在插件加载时进行赋值,以便应用程序能够调用插件的功能。 接下来,我们需要实现一个插件管理器,用于动态加载和卸载插件插件管理器可以扫描指定目录下的插件文件,并将其加载到应用程序中。加载插件时,插件管理器会使用 dlopen 函数将插件文件加载到内存中,并获取插件的函数指针。卸载插件时,插件管理器会使用 dlclose 函数将插件从内存中移除。 最后,我们可以编写一个简单的应用程序,使用插件框架来扩展其功能。这个应用程序可以使用插件管理器加载各种插件,并调用插件中的函数来执行相应的操作。 通过这个 C 插件框架 demo,我们可以了解到插件框架的基本原理和实现方。使用插件框架可以使应用程序更加灵活和可扩展,用户可以根据需要自定义和添加插件,以满足不同的功能需求。 ### 回答2: 插件框架 demo是指一个展示插件框架功能和用法的示例程序。插件框架是一种允许开发者轻松扩展和定制应用程序功能的架构。通过使用这个框架,开发者可以开发自己的插件,并将其集成到应用程序中,增加新的功能或修改现有功能。插件框架提供了一种灵活的方来定制应用程序,使其可以满足不同用户或场景的需求。 插件框架 demo通常包含以下内容: 1. 插件注册和加载:演示如何将插件注册到框架中,并实现插件的加载和初始化过程。通过这个示例,开发者可以学习到如何管理和控制插件的生命周期。 2. 插件接口和扩展点:插件框架通常定义了一些接口和扩展点,插件可以实现这些接口,并通过扩展点与应用程序进行交互。演示示例应该展示如何创建接口和扩展点,并在插件中实现它们。 3. 插件运行时环境:插件框架通常提供了一个运行时环境,用于加载和执行插件。演示示例应该展示如何配置和启动这个运行时环境,并演示插件的加载和执行过程。 4. 插件的使用和调试:演示示例应该展示如何在应用程序中使用已经加载的插件,并提供一些调试工具和方法,以便开发者能够更好地查看和调试插件的运行时数据。 通过这个插件框架 demo,开发者可以快速入门并理解插件框架的概念和用法,为开发自己的插件提供了一个良好的起点。希望通过这个示例能够帮助开发者更好地使用和扩展应用程序的功能。 ### 回答3: c插件框架demo是指以C语言为基础构建插件框架展示。插件是一种独立的软件模块,可以在应用程序中动态加载和卸载,以增强其功能。插件框架则是为插件管理和扩展提供支持的软件架构。 在c插件框架demo中,首先需要定义插件的基本结构和接口。每个插件都应该包括一个初始化函数和一个功能函数。初始化函数用于初始化插件的环境,功能函数则是插件的具体功能实现。通过定义统一的接口,可以方便地管理和调用各个插件。 接下来,在框架中实现插件的加载和卸载功能。插件可以存储在特定的目录中,框架通过读取插件目录获取所有的插件文件,并将它们加载到内存中。加载后,框架调用插件的初始化函数来进行初始化工作。当不需要插件时,可以通过调用插件的卸载函数将其从内存中卸载。 此外,框架还需要提供插件管理功能。可以实现插件的启动、停止和重启等操作。同时,框架可以提供插件的配置接口,允许用户对插件进行配置和自定义。 最后,在c插件框架demo中,可以编写一些示例插件来展示其应用和功能。示例插件可以实现一些常见的功能,如文件操作、网络通信等。通过演示这些插件,可以帮助用户更好地理解和使用插件框架。 总之,c插件框架demo通过展示插件的加载、卸载和管理等功能,为用户提供了一个灵活且易于扩展的软件架构。用户可以根据自己的需求,编写或集成各种插件,从而为应用程序增加更多的功能和特性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值