zoukankan      html  css  js  c++  java
  • C#反射调用其它DLL的委托事件 传值

    在插件式开发。我们要调用其它插件或模块的委托事件时、那么我们需要通过反射。

    Module 模块
    namespace Module2
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        [Plugin("MainWindow", "测试反射")]
        public partial class MainWindow 
        {
            public delegate void TestHandler(string msg,string info,string text);
            public event TestHandler TestEvent;
    
            public MainWindow()
            {
                InitializeComponent();
            }
    
            protected virtual void ValueInformation(string text, string info, string tb)
            {
                TestHandler handler = TestEvent;
                if (handler != null)
                    handler(text,info,tb);
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                if (TestEvent != null)
                {
                }
                ValueInformation("你好!钓鱼岛是中国的!!","打死小日本!!",textBox1.Text);
            }
    
            public override void UninstallEvent()
            { 
                //添加已经打开的窗口 :在关闭的时候 要删除此项
                ApplicationSharedData.LoadedPlugins.Remove("Module2.MainWindow");
                base.UninstallEvent();
            }
        }
    }
    反射
     1 /// <summary>
     2         /// 模块之间 委托事件 通信
     3         /// </summary>
     4         /// <param name="currentWindow">当前的Window</param>
     5         /// <param name="reflectioneventName">要反射模块中的 委托事件名称</param>
     6         /// <param name="currentEventName">在当前类中要执行的事件名称</param>
     7         /// <param name="filePath">反射文件的路经</param>
     8         /// <param name="plugin">插件</param>
     9         /// <param name="eventParameter">通信的消息</param>
    10         public static void ModulEventCommunication(Window currentWindow, string reflectioneventName,
    11                                                    string currentEventName, string filePath, Plugin plugin,
    12                                                    object[] eventParameter)
    13         {
    14             if (reflectioneventName == null)
    15                 throw new ArgumentNullException("reflectioneventName");
    16             if (currentEventName == null)
    17                 throw new ArgumentNullException("currentEventName");
    18             if (filePath == null)
    19                 throw new ArgumentNullException("filePath");
    20             if (eventParameter == null)
    21                 throw new ArgumentNullException("eventParameter");
    22             try
    23             {
    24                 Assembly assembly = Assembly.LoadFrom(filePath + plugin.NameSpace + "." + plugin.Exends);
    25                 Type[] type = assembly.GetTypes();
    26                 foreach (Type t in type)
    27                 {
    28                     //主要是判断该窗口是否实现 IElementsView 如果没有实现 就不需要反射或者不是插件 
    29                     if (t.GetInterface("IElementsView") != null && t.Name == plugin.ClassName)
    30                     {
    31                         //注:在这里要判断是否已经加载:
    32                         if (LoadedPlugins.Contains(t.FullName))
    33                         {
    34                             return;
    35                         }
    36                         //反射执行的成员和类型搜索
    37                         const BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
    38                         EventInfo eventInfo = t.GetEvent(reflectioneventName, myBindingFlags);
    39                         //获取到当前的类
    40                         var obj = (IElementsView)assembly.CreateInstance(t.FullName);
    41                         if (eventInfo != null)
    42                         {
    43                             Type tDelegate = eventInfo.EventHandlerType;
    44                             MethodInfo methodHandler = currentWindow.GetType().GetMethod(currentEventName,myBindingFlags);
    45                             //创建委托
    46                             Delegate d = Delegate.CreateDelegate(tDelegate, methodHandler);
    47                             //获取将要处理的事件委托
    48                             MethodInfo minAddHandler = eventInfo.GetAddMethod();
    49                             object[] addHandlerArgs = { d };
    50                             //调用
    51                             minAddHandler.Invoke(obj, addHandlerArgs);
    52                             FieldInfo field = t.GetField(reflectioneventName,
    53                                                         myBindingFlags);
    54                             if (field != null)
    55                             {
    56                                 Object fieldValue = field.GetValue(obj);
    57                                 if (fieldValue != null && fieldValue is Delegate)
    58                                 {
    59                                     Delegate objectDelegate = fieldValue as Delegate;
    60                                     //动态调用
    61                                     objectDelegate.DynamicInvoke(eventParameter);
    62                                 }
    63                             }
    64                         }
    65                         if (obj != null)
    66                         {
    67                             obj.ShowWindow();
    68                             //添加已经打开的窗口 :在关闭的时候 要删除此项
    69                             LoadedPlugins.Add(t.FullName);
    70                         }
    71                     }
    72                
    73                 }
    74             }
    75             catch (FileNotFoundException)
    76             {
    77                 MessageBox.Show("尊敬的用户您好!没有找到相应的模块!", "插件提示!", MessageBoxButton.OK,
    78                                   MessageBoxImage.Information);
    79             }
    80             catch (TargetParameterCountException)
    81             {
    82                 MessageBox.Show("尊敬的用户您好!在调用模块时发现委托的参数不同!请检查参数的个数!", "插件提示!", MessageBoxButton.OK,
    83                                 MessageBoxImage.Information);
    84             }
    85             catch (Exception)
    86             {
    87                 MessageBox.Show("尊敬的用户您好!系统发现版本与当前系统不匹配!", "插件提示!", MessageBoxButton.OK,
    88                                 MessageBoxImage.Information);
    89             }
    90         }


    本模块调用:

    调用反射信息
     void Test2_Click(object sender, RoutedEventArgs e)
            {
                var item = (MenuItem)sender;
                string path = @Environment.CurrentDirectory + "\\";
                Plugin plugin = ApplicationSharedData.Plugins[item.Header.ToString()];
    
                ApplicationSharedData.ModulEventCommunication(this, "TestEvent", "DeleBindData", path, plugin, new object[] { "参数1", "参数2","" });
                //注 在反射TestEvent 时候 ,TestEvent有几个参数 那么S_TestEvent 也有几个参数。
                //不然会抛出异常信息,TargetParameterCountException 参数的个数不同
            }
    
    
            private static void DeleBindData(string msg, string info,string tb)
            {
                _textbox.Text = tb;
            }

    此代码是我在一次开发中遇到的问题。。在这里做个备注 ,防止下次忘记了。。

    .net企业级架构开发

  • 相关阅读:
    套接字和域名系统DNS
    TCP滑动窗口控制流量的原理
    AngularJS 路由
    使用纯前端JavaScript 实现Excel IO
    Deferred在jQuery和Angular中的使用与简单实现
    深入理解函数声明和函数表达式(转)
    Visual Studio Code 智能提示文件
    JavaScript框架设计(四) 字符串选择器(选择器模块结束)
    JavaScript框架设计(三) push兼容性和选择器上下文
    canvas学习和面向对象(二)
  • 原文地址:https://www.cnblogs.com/w2011/p/2837614.html
Copyright © 2011-2022 走看看