zoukankan      html  css  js  c++  java
  • 利用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     }
    复制代码
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace UnityTest
    {
        using System.Diagnostics;
        using System.Windows.Forms;
        using Microsoft.Practices.Unity.Configuration;
        using Microsoft.Practices.Unity;
        using System.Configuration;
    
        public interface IMessage
        {
            DateTime Time { get; set; }
            string Text { get; set; }
            string ToString(string split);
        }
        public class MyMessage:IMessage
        {
            public DateTime Time { get; set; }
            public string Text { get; set; }
            public MyMessage(string text,DateTime time)
            {
                Text = text;
                Time = time;
            }
            public MyMessage(string text):this(text,DateTime.Now){}
           
            public string ToString(string split ="\t")
            {
                return Time.ToString() + split + Text +split+ GetHashCode();
            }
        }
        public interface ITrace
        {
            IMessage Message { get; set; }
            void Write(string message);
        }
        public class ConsoleTrace:ITrace
        {
            [Dependency]
            public IMessage Message { get; set; }
            public void Write(string message)
            {
                if (Message != null)
                {
                    message = Message.ToString("\t");
                }
                Trace.WriteLine(message);
            }
        }
        public class FormTrace:ITrace
        {
            public IMessage Message { get; set; }
            public void Write(string message)
            {
                if (Message != null)
                {
                    message = Message.ToString("\t");
                }
                Trace.WriteLine(message);
            }
        }
        public class Class1
        {
            public void test1()
            {
                IUnityContainer container = new UnityContainer();
                IUnityContainer childContainter = container.CreateChildContainer();
    
                ExeConfigurationFileMap map = new ExeConfigurationFileMap();
                map.ExeConfigFilename = "UnityTest.dll.config";
                System.Configuration.Configuration config
                    = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
                UnityConfigurationSection section= (UnityConfigurationSection)config.GetSection("unity");
                var defultContainter =  config.AppSettings.Settings["DefultContainter"].Value;
                section.Configure(container, defultContainter);
    
                section.Configure(childContainter, "First");
                //container.LoadConfiguration("Fourth");
                //container.RegisterType<ITrace, CosoleTrace>(new ContainerControlledLifetimeManager());
                //container.RegisterType<ITrace, FormTrace>();
    
                var message = container.Resolve<IMessage>();
                Trace.WriteLine(message.ToString("\t"));
    
                message.Text = "1111";
    
                var trace = childContainter.Resolve<ITrace>();
                trace.Message = message;
                trace.Write("fdsfds");
    
                trace = childContainter.Resolve<ITrace>();
                //trace.Message = message;
                trace.Write("fdsfds");
    
                trace = childContainter.Resolve<ITrace>();
                trace.Write("fdsfds");
    
                //container.LoadConfiguration("Second");
                //trace = container.Resolve<ITrace>();
                //trace.Write("fdsfds");
            }
        }
    }
    复制代码
    复制代码
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name ="unity" type ="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
                 Microsoft.Practices.Unity.Configuration"/>
      </configSections>
      <appSettings>
        <add key ="DefultContainter" value="ChildContainter"/>
      </appSettings>
      <unity xmlns ="http://schemas.microsoft.com/practices/2010/unity">
        <namespace  name="UnityTest"/>
        <assembly name="UnityTest"/>
        <container name="ChildContainter">
          <register type="IMessage" mapTo="MyMessage">
            <constructor>
              <param name="text" type="System.String" value="abc"/>
            </constructor>
          </register>
        </container>
        <container name="First">
          <register  type="ITrace" mapTo="ConsoleTrace">
            <lifetime type="singleton"/>
          </register>
        </container>
        <container name="Second">
          <register type="ITrace" mapTo="FormTrace">
            <lifetime type="singleton"/>
          </register>
        </container>
        <container name="Third">
          <register type="ITrace" mapTo="ConsoleTrace">
            <lifetime type="perresolve"/>
          </register>
        </container>
        <container name="Fourth">
          <register type="ITrace" mapTo="ConsoleTrace">
            <lifetime type="perthread"/>
          </register>
        </container>
      </unity>
    </configuration>
    复制代码

    配置Unity有两种方法:利用配置文件配置;在程序代码中配置。

    The Unity StopLight QuickStart为例:

    在程序中用代码配置,这种方法重新配置需重新编译程序。

                IUnityContainer container = new UnityContainer()
                    .AddNewExtension<SimpleEventBrokerExtension>();
                    .RegisterType<ILogger, TraceLogger>()
                    .RegisterType<IStoplightTimer, RealTimeTimer>();

    另一种方式是利用配置文件配置:配置文件配置是应添加

    xmlns ="http://schemas.microsoft.com/practices/2010/unity",这样可以利用xsd架构来智能感知。
    复制代码
     <configSections>
        <section name ="unity" type ="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
                 Microsoft.Practices.Unity.Configuration"/>
      </configSections>
      <unity xmlns ="http://schemas.microsoft.com/practices/2010/unity">
        <namespace name="StopLight.ServiceInterfaces"/>
        <namespace name="StopLight.ServiceImplementations"/>
        <namespace name="StopLight.UI"/>
        <namespace  name="StopLight.Logic"/>
        <assembly name="StopLight"/>
        <container>
          <register type="ILogger" mapTo="TraceLogger"/>
          <register type="IStoplightTimer" mapTo="RealTimeTimer"/>
          <register type="Stoplight">
            <property name="Logger" dependencyType="ILogger" dependencyName="TraceLogger"/>
          </register>
          <register type="StoplightSchedule">
            <property name="Logger"  dependencyType="ILogger" dependencyName="TraceLogger"/>
          </register>
          <register type="StoplightPresenter">
            <property name="Stoplight" dependencyType="Stoplight" dependencyName="Stoplight"/>
            <property name="Schedule" dependencyType="StoplightSchedule" dependencyName="StoplightSchedule"/>
          </register>
        </container>
      </unity>
    复制代码
     
        IUnityContainer container = new UnityContainer();
    
                UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
               
                section.Configure(container);
    分类: .netC#
  • 相关阅读:
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 实现业务
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 开发流程
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 报表系统集成说明
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 处理报表
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 数据访问
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 分布式应用
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 实现插件
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 对象设计器使用帮助
    基于DotNet构件技术的企业级敏捷软件开发平台 AgileEAS.NET平台开发指南 数据层开发
    Jquery 中的CheckBox、 RadioButton、 DropDownList、CheckBoxList、RadioButtonList的取值赋值
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2496750.html
Copyright © 2011-2022 走看看