利用Unity来实现插件开发

1649 篇文章 12 订阅
1623 篇文章 23 订阅

论坛里有许多插件开发的文章,本文就不长篇大论了,说一下我的简单思路:

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     }
复制代码

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值