利用Unity來實現插件開發


論壇里有許多插件開發的文章,本文就不長篇大論了,說一下我的簡單思路:

1、建一個IPlugin接口,每個插件都要繼承這個接口。

2、建一個插件管理類,利用Unity來管理各個插件。

 

 1     using System.Reflection;
 2     using Microsoft.Practices.Unity;
 3     public  interface IPlugin
 4     {
 5         void LoadPlugin();
 6         string PluginName { get; }
 7     }
 8     public class PlugInManage
 9     {
10         /// <summary>
11         /// 從dll、exe文件中獲取繼承IPluin接口的所有類的類型信息
12         /// </summary>
13         /// <param name="path">文件路徑</param>
14         /// <returns>類型信息(插件名稱,(插件類名稱,插件所在程序集名稱))</returns>
15         public static Dictionary<string, string> Load(string path)
16         {
17             if (!System.IO.Directory.Exists(path))
18             {
19                 throw new System.IO.DirectoryNotFoundException();
20             }
21 
22             Dictionary<string, string> pluins = new Dictionary<string,string>();
23             var files = System.IO.Directory.GetFiles(path);
24             foreach (var file in files)
25             {
26                 if (file.ToLower().EndsWith(".exe") || file.ToLower().EndsWith(".dll"))
27                 {
28                     var assembly = Assembly.LoadFrom(file);
29                     var types = assembly.GetTypes();
30                     foreach (var type in types)
31                     {
32 
33                         if (type.GetInterfaces().Count(c =>c == typeof(IPlugin)) > 0)            
34                         {
35 
36                             IPlugin instance = assembly.CreateInstance(type.FullName) as IPlugin;
37                             if (instance != null)
38                             {
39                                 _container.RegisterType(typeof(IPlugin), type, type.FullName, new ExternallyControlledLifetimeManager());
40 
41                                 var name = string.IsNullOrEmpty(instance.PluginName) ? 
42                                     type.FullName : instance.PluginName;
43                                 name = pluins.ContainsKey(name)?name+"_1":name;
44                                 pluins.Add(name, type.FullName);
45                             }
46 
47                         }
48                     }
49                 }
50             }
51             return pluins;
52         }
53 
54         static IUnityContainer _container = new UnityContainer();
55         public static IPlugin Resolve(string name)
56         {
57             GC.Collect();
58             return _container.Resolve<IPlugin>(name);
59         }
60 
61     }

 

3、注意容器內注冊的類型應為ExternallyControlledLifetimeManager類型的生命周期,外部控制生命周期管理器,這個生命周期管理允許你使用RegisterType和RegisterInstance來注冊對象之間的關系,但是其只會對對象保留一個弱引用,其生命周期交由外部控制,也就是意味着你可以將這個對象緩存或者銷毀而不用在意UnityContainer,而當其他地方沒有強引用這個對象時,其會被GC給銷毀掉。在默認情況下,使用這個生命周期管理器,每次調用Resolve都會返回同一對象(單件實例),如果被GC回收后再次調用Resolve方法將會重新創建新的對象。

測試如下:

using XZL.Plugin;
    public partial class Form1 : Form
    {
        Dictionary<string, string> _plugins;
        public Form1()
        {
            InitializeComponent();
            this.Load += new EventHandler(Form1_Load);
            this.button1.Click += new EventHandler(button1_Click);
        }

        void button1_Click(object sender, EventArgs e)
        {
            var p =  PlugInManage.Resolve(_plugins[listBox1.SelectedItem.ToString()]);
            p.LoadPlugin();
            //GC.Collect();

        }

        void Form1_Load(object sender, EventArgs e)
        {
            _plugins =  PlugInManage.Load(System.IO.Path.GetDirectoryName(Application.ExecutablePath)
                + "\\" + "plugins");
            foreach (var item in _plugins)
            {
                listBox1.Items.Add(item.Key);
            }
        }
    }

 

 1     using XZL.Plugin;
 2     public partial class Form1 : Form,IPlugin
 3     {
 4         public Form1()
 5         {
 6             InitializeComponent();
 7         }
 8 
 9         public void LoadPlugIn()
10         {
11             this.Show();
12         }
13 
14 
15         string IPlugin.PluginName
16         {
17             get { return this.Text; }
18         }
19     }

 


免責聲明!

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



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