473,761 Members | 2,410 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

C# win: Using Reflection to create universal event handlers

Plater
7,872 Recognized Expert Expert
I'm a bit boggled by this since I am rather new to using reflection.
I want to attach an event handler via Reflection (which I can do), but I want to NOT have to know the exact event delegate signature.

For an exmaple, I have a .DLL with the following:
Expand|Select|Wrap|Line Numbers
  1. public delegate CustomEnum CustomEventHandler(Socket s, CustomClass c);
  2. public class myclass
  3. {
  4.    public event CustomEventHandler MyEvent;
  5.    //...
  6. }
  7. public enum CustomEnum
  8. {
  9.    //...
  10. }
  11. public class CustomClass
  12. {
  13.    //...
  14. }
  15.  

I want to be able to:
*load the DLL from reflectionlike a plugin would do (done)
*Instanciate an instance of "myclass" (done)
*Attach an event handler to "MyEvent" (trouble)

If the Event signature was of <SomeRegularTyp e> MyEvent(<SomeRe gularType> whatever, etc, etc)
I could cheat and create a handler at design time that matches the signature.
BUT the problem is that the customtypes are ALSO kept in the DLL, so I cannot use the types at design time.

I tried creating an eventhandler like this:
object MyEventHandler( object s, object cc);
But the AddHandler() call fails because the delegate signature is not the same.
(I did a test with a regular event that was void MyEvent(string s) and tried using void MyEventHandler( object s) and it also failed)

So I am questioning how this is done? Do I change the signature in the DLL to be of
object MyEvent(object s, object CC) and then do all the .GetType() matching inside the handler function I create?

Seems like there should be a better way to do this.

Anyone have any thoughts?
Nov 10 '08 #1
10 9579
Plater
7,872 Recognized Expert Expert
Well I am still cheating a lot, but I am making progress. I can now create the event I want, using types contained inside
Given (this is kept in plater.dll):
Expand|Select|Wrap|Line Numbers
  1.  
  2. namespace Plater
  3. {
  4. public delegate CustomEnum CustomEventHandler(Socket s, CustomClass c); 
  5. public class myclass 
  6.    public event CustomEventHandler MyEvent; 
  7.    //... 
  8. public enum CustomEnum 
  9.    //... 
  10. public class CustomClass 
  11.    //... 
  12. }
  13. }
  14.  
  15.  

Expand|Select|Wrap|Line Numbers
  1. Assembly asm = Assembly.LoadFrom("plater.dll");
  2. object[] myparams= new object[0];
  3. object myobj = asm.CreateInstance("Plater.myclass", true, BindingFlags.Default, null, myparams, null, null);
  4.  
  5. Type A = asm.GetType("Plater.CustomEnum");
  6. Type B = typeof(System.Net.Sockets.Socket);
  7. Type C = asm.GetType("Plater.CustomClass");
  8.  
  9. EventInfo peEv2 = myobj.GetType().GetEvent("MyEvent");
  10. MethodInfo RRMeth = typeofClassWithGenericStaticMethod.GetMethod("o_MyEvent", System.Reflection.BindingFlags.Static | BindingFlags.NonPublic);
  11. Type[] RRtypestoSend = new Type[] { A,B,C};
  12. MethodInfo RRMethToAttach = RRMeth.MakeGenericMethod(RRtypestoSend);
  13. Delegate peDel2 = Delegate.CreateDelegate(peEv2.EventHandlerType, RRMethToAttach);
  14. peEv2.AddEventHandler(myobj, peDel2);
  15.  
  16. private static void o_MyEvent<A>(A msg)
  17. {
  18.     MessageBox.Show(msg.GetType().ToString()); 
  19. }
  20.  
The eventhandler DOES get triggered as it should.

Places where I still cheat:
1)Knowing the signature of the event (to create the <A,B,C> eventhandler)
2)Knowing how many types are used (to create the type[] to send)
3)Knowing which types to grab (to do the asm.GetType(str ing) )

Now, knowing 1) pretty much tells you 2) and 3), but I still think there still should be a way to map an event to a function of maybe:
object myfunc(params object[] paras)
Visual Studio has to know how to read an event and decide on the signature parameters in order to do its auto-create for the eventhandler.
Nov 13 '08 #2
balabaster
797 Recognized Expert Contributor
Feel free to tell me if I'm missing what you're asking:

Custom event args usually hold relevant data to the event, and they should inherit from System.EventArg s - if the coder follows standards, which I'm certain you do :oP

So that will allow you the ability of attaching a handler without knowing the correct signature. However - it won't allow you access to the custom properties of e.

a la:
eventhandler MyGenericEventH andler(object Sender, EventArgs e)

object.event += MyGenericEventH andler

In order to access the custom properties, you're going to need to cast e to its native type...which we can't know until we reflect on it.

I've run into this situation before where I needed to be able to cast an object as a type only known at runtime and I came up against a wall. I'll have another play and see what I can come up with but from previous experience I'm doubtful I'm going to be successful...

Or are you trying to grab the event handler that's already defined inside the class and attach it to the parent application? Maybe I'm just not following quite what you're after...
Nov 13 '08 #3
balabaster
797 Recognized Expert Contributor
Here's a rather amusing thread that's trying to achieve the same thing - albeit for a different purpose. It's mostly amusing because the person trying to assist seems to completely miss the point of the person trying to get assistance and they spend many posts running around in circles before coming up with no suitable conclusion...

But agreed, this is a situation where you would need this ability.

Although, I guess you could use GetProperty and SetProperty on the reflected object - that should work... which is what they allude to. Not sure if it'll work though yet as I haven't tried it...
Nov 14 '08 #4
balabaster
797 Recognized Expert Contributor
I'm not sure if you've come across this yet - but it may be a pointer in the right direction:

http://msdn.microsoft. com/en-us/library/system.reflecti on.eventinfo.ad deventhandler.a spx
Nov 14 '08 #5
Plater
7,872 Recognized Expert Expert
Custom event args usually hold relevant data to the event, and they should inherit from System.EventArg s - if the coder follows standards, which I'm certain you do :oP
While I AM a big fan of coding to standards, the DLL is written for (and needs to continue to work on) an limited system Compact framework, where reflection isn't really feasable.

Perhaps I am a bit to vague for generallity sake.
I wrote a webserver in the form of a dll for a project at work.
The dll has a class that handles all the socket business of reading in the http request and building a custom request object (also contained in the dll).
This class exposes TWO events with the following signatures
void NotifyMessage(s tring msg)
Plater.ThreadSt ate RequestReceived (Socket s, Plater.RequestO bject)

Plater.ThreadSt ate, Plater.RequestO bject are contained only in the DLL.

Now with my last post I was able to cheat, and do the Assembly.Load() , create an instance of my class and attach eventhandlers to each event, partially because I knew that I gould call a .GetType() on the ThreadState and other objects, and partially because i abused the generics properties on a method.

Now this is functional for what I was after, I was just wondering for a more universal implementation.
I just want my program to go "hey, the httplistener.dl l is here, I might as well run a webserver" or "no dll, guess i will carry on without serving webpages"


EDIT:
Not sure why I am being a helmet and thinking I need to use Reflection in the CE version, it will have a legitamate reference to the dll and can use the types like normal.
I suppose I should rewrite the events to match standard handlers, the event that requires a return value: I can create a custom eventargs that has an object inside it, then I can change that object and read it back again at the palce where i called the event, to mimic a return value right?
Nov 14 '08 #6
balabaster
797 Recognized Expert Contributor
EDIT:
Not sure why I am being a helmet and thinking I need to use Reflection in the CE version, it will have a legitamate reference to the dll and can use the types like normal.
I suppose I should rewrite the events to match standard handlers, the event that requires a return value: I can create a custom eventargs that has an object inside it, then I can change that object and read it back again at the palce where i called the event, to mimic a return value right?
I reread your post 3 times before you put that edit and could've sworn I was missing something in your reasoning for needing reflection in the CE version... all the CE version is doing is passing the DLL, right? The version that's being passed the DLL is doing all the work, so yeah, I'd modify the object so that it's coded using the standard whereby e inherits from System.EventArg s and presto you're home free...
Nov 14 '08 #7
Plater
7,872 Recognized Expert Expert
home free...
"Home free" being that I don't need to cheat with the event handlers per-say.
I did discover I rather like this:
Expand|Select|Wrap|Line Numbers
  1. public static Dictionary<string, object> GetProperties(object ReflectedObject)
  2. {
  3.     Dictionary<string, object> retval = new Dictionary<string, object>();
  4.     if (ReflectedObject != null)
  5.     {
  6.         MemberInfo[] mems = ReflectedObject.GetType().GetMembers();
  7.         foreach (MemberInfo mi in mems)
  8.         {
  9.           if (mi.MemberType == MemberTypes.Property)
  10.           {
  11.             string name = mi.Name;
  12.             object o = ReflectedObject.GetType().InvokeMember(name, BindingFlags.GetProperty, null, ReflectedObject, null);
  13.             retval.Add(mi.Name, o);
  14.           }
  15.         }
  16.     }
  17.     return retval;
  18. }
  19.  
  20.  
I know there is a .GetProperties on the Type, but I did it this way in case I wanted some other form of members in there too
Nov 14 '08 #8
balabaster
797 Recognized Expert Contributor
Yep... looks like it should work pretty well. You can attach a generic handler, grab e and then just reflect over it to grab the properties as necessary.
Nov 14 '08 #9
balabaster
797 Recognized Expert Contributor
Hey man - did you get this working in the end? If so, what did you do?
Nov 17 '08 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

2
1564
by: D. Patterson | last post by:
Hello all. I've a bit of a problem. I would like to use a method in an object as an event handler. Unfortunately, when the method is called the "this" object references the event trigger rather than my object. For example, with the following code, an alert will be shown when the page loads where the value of my_name is "My Object" and nodeName is 'undefined". Dismissing
13
3518
by: Charles Law | last post by:
Mr "yEaH rIgHt" posted the following link about a week ago in answer to my question about removing event handlers. > http://www.vbinfozine.com/t_bindevt.shtml Following on from that post, the following issues still exist. The article shows how to find methods on a receiver that match the pattern OnXXXX given the sender. It loops through the sender events and tries to get methods from the receiver that match the pattern. For each one...
1
1581
by: Samuel R. Neff | last post by:
Is there any way to create a generic event handler that can be subscribed to any event? If I have a sub.. Private Sub DataTable_SomethingChanged(sender As Object, e As System.EventArgs) and subscribe it to AddHandler dataTable.ColumnChanged, AddressOf SomethingChanged
2
1632
by: mike | last post by:
i'm building an desktop windows app in C#. the main menu for the application will be different depending on the admin rights of the user. i've built the entire app. in delphi and i simply activated or deactivated the menu items in that case, but all the menu items are visble. i'm hoping / thinking that with .NET, i can dynamically generate the click events for the dynamically generated menu, so that only the menu items, that a particular...
16
2516
by: Hamed | last post by:
Hello I am developing a utility to be reused in other programs. It I have an object of type Control (a TextBox, ComboBox, etc.) that other programmers use it in applications. they may set some of properties or assign event handlers. I need to be able to clone the manipulated control at runtime. I could use the Clone method of some objects (like Font, Style, String,
14
8638
by: Hamed | last post by:
Hello It seems that I should implement ICloneable to implement my own clone object. the critical point for me is to make a control object based on another control object that all of its event handlers are set like the old one. Is there a way to do this job? For example, is there a way to use EventInfo object to get all event handlers of the old control in runtime and set my new cloned control events to the event handlers of the old...
5
1418
by: Chris | last post by:
Is there any way you can dynamically add an event and then some code. I get it that you could, in your code, add a control and dynamically add an event handler for e.g. the click event. However the code within the event handler, could that be pulled from a database and ran. I would like to create a form in which I could populate it's controls and events based on config information in either a database or xml file e.g. how many textboxes...
2
2752
by: Grzegorz Danowski | last post by:
Hello, I'd like to hide control if any of its event handlers is forbidden for current user (basing on PrincipalPermissionAttribute). How to list all methods that handle given event? I supposed that I should use reflection and I examined EventInfo class but I haven't found in this class any information about handlers list, but there is a possibility to add one (AddEventHandler method). --
3
3015
by: =?Utf-8?B?ZWFndWlsYXI=?= | last post by:
Hi, I am trying to dynamically generate a menu, based on entries on a text or xml file. The text file contains the "tree" after which the menu will need to be created. Something like the following: Level 1 -- Level 2 -- Level 2 Level 1
0
9531
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9957
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9905
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9775
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8780
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7332
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6609
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5229
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
3
2752
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.