也來學學插件式開發續-利用MEF


前面一個博客:也來學學插件式開發中很多朋友留言說可以用MEF來實現。於是我就試着用MEF實現了一下。

步驟和上一篇差不多,只是加載插件的方式有所不同。這只是一個自己的示例程序,肯定有很多不足之處,歡迎拍磚。

MEF如何工作?

MEF主要是通過ImportExport特性來定義導入與導出部件。程序在運行的時候會將具有相同接口的導出的實例化,賦給導入。

MEF程序設計指南一:在應用程序中宿主MEF這篇文章有一個簡單的MEF例子,大家可以參考一下。

所以,在這里,插件就是導出,我們在程序中要定義具有和插件相同接口的導入。

但是這里有一個問題,一般的導入與導出是一對一的,但我們的工具箱中和插件的關系明顯是一對多的怎么辦?

沒問題,MEF對於這種情況可以將導入聲明為ImportMany,這樣就支持一個導入對應多個導出了。

關於ImportMany可參見:http://msdn.microsoft.com/en-us/library/dd460648.aspx#further_imports_and_importmany

因此這里,我用ImportMany來定義一個集合來保存插件:

        [ImportMany]
        public IEnumerable<Iplugin> plugins;

如何讓MEF發現插件?

我們用反射的時候是將插件放置在一個固定的目錄中,然后再去掃描這個目錄來發現插件,在MEF中如何來發現插件呢?

MEF提供三種方式發現部件:

  1. AssemblyCatalog 在當前程序集發現部件。
  2. DirectoryCatalog 在指定的目錄發現部件。
  3. DeploymentCatalog 在指定的XAP文件中發現部件(用於silverlight)

可以看到,我們也可以將插件放在統一的目錄讓MEF去檢索發現。

使用MEF

使用MEF的時候,首先要初始化MEF的組合容器對象:CompositionContainer,所以在窗體加載的時候要做好初始化工作。

        public ToolBox()
        {
            InitializeComponent();
            Init();
        }
        private CompositionContainer _container;

        private void Init()
        {
            //An aggregate catalog that combines multiple catalogs
            var catalog = new AggregateCatalog();
            //設置目錄
            catalog.Catalogs.Add(new DirectoryCatalog(Application.StartupPath + "\\plugin\\"));

            //Create the CompositionContainer with the parts in the catalog
            _container = new CompositionContainer(catalog);

            //Fill the imports of this object
            try
            {
                this._container.ComposeParts(this);
            }
            catch (CompositionException compositionException)
            {
                Console.WriteLine(compositionException.ToString());
            }
        }

接着就是發現插件后的顯示工作了:

        private void ToolBox_Load(object sender, EventArgs e)
        {
            InitPlugin();
        }

        [ImportMany]
        public IEnumerable<Iplugin> plugins;


        public void InitPlugin()
        {
            foreach (Iplugin plugin in plugins)
            {
                InitModule(plugin);
            }
        }

增加插件

我們來新增一個插件試試。新建一個類庫項目,再增加一個Window窗體,拉一個PictureBox,顯示一張圖片。主要的工作是我們要定義導出:Export

   [Export(typeof(PluginMain.Interface.Iplugin))]
    public class App:PluginMain.Interface.Iplugin
    {
        public System.Windows.Forms.Form MainForm
        {
            get { return new Picture(); }
        }

        public System.Drawing.Image ModulePicture
        {
            get { return null; }
        }
    }

將生成的.DLL放在plugin目錄中。生成后效果如圖:

 示例代碼下載:點我

 

參考資料:【.Net平台下插件開發】-MEF與MAF初步調研

             《MEF程序設計指南》博文匯總

             Managed Extensibility Framework (MEF)


免責聲明!

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



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