プラグインのようなアプリケーションフレームを構築する(五)-プラグインを管理する


もっと読む
 私達は今すでにプラグイン式のアプリケーションのフレームワークを構築しました.次の仕事はフレームの内容を充実させ、基本的なサービスを提供します.つまりServiceです.まず第一の任務はプラグインの管理サービスを提供することです.前の文章でも言及しました.動的ローディングを実現するにはプラグインの寄宿先がどこにあるかを知っていなければなりません.どれをローディングしますか?
まず解決したのはプラグインをどこに置くかということです.私がとってきた伝統的な方法は、アプリケーションのあるディレクトリの下にプラグインを置いて作成したディレクトリです.次の作業は、どのプラグインがロードされるかを通知します.どれがロードされる必要がないかを教えます.これらの情報をアプリケーションの設定ファイルの設定ブロックに入れます.アプリケーションが実行されると、設定ファイルを読み込み、得られた情報に基づいてプラグインをロードします.また、私たちのアプリケーションのフレームワークは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();
    }
}
Plugin Serviceが達成する目的は、まず、ロードするプラグインと関連する情報を設定ファイルに追加/削除し、次に動的なプラグインをロードすることです.いくつかのタイプを定義します.ブロックタイプ、Plugin要素タイプ、plugin要素セットタイプは、プラグインの情報を読み取ることができます.
最後にPlugin Serviceを実現します.
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 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 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を使ってプラグインを管理するところが必要です.私のやり方はメニューに項目を追加し、ユーザーがこの項目をクリックするとプラグイン管理のダイアログが表示されます.ユーザーはこのダイアログでプラグインを使用することを選択します.プラグインが選択されると、プラグインはすぐにロードされます.また、設定ファイルに記録しておくと、ユーザーが次のアプリケーションを実行すると、プラグインはデフォルトで自動的にロードされます.
また、これからはプロファイルを使う必要があります.だから、アプリケーションにap.co.nfigファイルを追加したいです.ファイルの内容は以下の通りです.
コピー 
保存
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