Continued from part 1
For the brave (and those with programming experience), CodeProject (as usual) has a lengthy, thorough article with a complete example.
See http://www.codeproject.com/KB/dotnet/Reflection.aspx if you wish.
My example is much more focused. So…how to call a certain method at runtime by passing a string…
Couple of “big deals” to keep in mind:
- Reflection should not be your first choice – thus far, I think of it as a “monkey wrench”. It works, but a regular box-end wrench holds much better. There are better tools for a job perhaps, but this will work
- Note that my example here could no doubt be redesigned I believe, but I thought reflection was appropriate based on the business and technical cases…plus it seemed like a fun topic to learn about and discuss!
- My “better tools” idea would probably mean rethinking what you are doing in general
- Reflection makes things more difficult to troubleshoot
- If you are changing your program at run time you are certainly changing the way it operates in a fashion different from simple user interaction, and if your method throws an exception, you may have trouble figuring out what caused it
- You may also be more likely to call the wrong method at the wrong time unintentionally – attention to detail is key
- From what I know of reflection, it seems like the concept of late binding – which hurts performance, thus I think it is reasonable to believe that reflection-based method calling is slower than traditional method invocation.
OK – here’s my code from my form class that runs the method passed in as a string.
code sample – reflection
Let’s break it down…
This dimensions the variable that will hold the passed in property which signifies what method to look up and invoke.
Private m_strLinkProcedureToRun As String
This is simply the property setup related to the above dim statement.
Public WriteOnly Property prop_strLinkProcedureToRun() As String
Set(ByVal value As String)
m_strLinkProcedureToRun = value
End Set
End Property
This part performs the “magic” of looking up the passed in string that matches a method in the selected module (modLink.vb in this case). Note that all the methods I can possible call here have to have the same number of parameters, and they have to be passed as an array. In this case, my method will use two strings. The first string (item 0 in the array) represents the main thing you are linking a record to (i.e. a user, etc.).
Dim t As Type = GetType(modLink) 'pick what module the sub or funct is in!
Dim m As MethodInfo = t.GetMethod(m_strLinkProcedureToRun) 'search for what we passed in
Dim array(1) As String 'create an array to hold our params
array(0) = m_strIdFromMainForm 'our first parameter - from the main grid
This part gets the id you selected that you wish to link to the “main ID” you passed in (i.e. group you want the user to be added to, etc.). Note that in the full code example, you will see two sections for this method call – this is a way to handle multiple selected items in the DevExpress XtraGrid control that this form uses. Here I just show you the single selection. The invoke method of the methodinfo class will run our desired sub or function, assuming it’s found. The array gets sent with both parameters.
array(1) = gridViewLink.GetFocusedRowCellValue(m_strIdInGridViewLink).ToString '2nd parameter
m.Invoke(Me, array) 'call the function we passed in as a variable
Here is an example of the call to create the class instance and show the form to the user. The XtraGrid on this class is public so it can be bound at runtime as needed – this could have been done with reflection as well, but I wanted to minimize the use to keep things simpler, at least to start with. You can ignore the various properties – the only real important one for our purposes is prop_strLinkProcedureToRun. You may also notice a call to a Fill_Grid sub – that refreshes our main grid after linking has taken place so we see the new relationship.
Dim frmX As New frmLink_Template
Dim strMainID As String = gridView_UserInv.GetFocusedRowCellValue("UserID").ToString
mod_Fill_Grid_UsersGroups_UsersInvLinkForm(strMainID, frmX.gridControlLink, frmX.gridViewLink)
frmX.prop_strIdFromMainGrid = strMainID
frmX.prop_strIdInGridViewLink = "GroupID"
frmX.prop_strFormTitle = "Link groups"
frmX.prop_boolEnableMultiSelectForGrid = True
frmX.prop_boolFormIsSizeable = False
frmX.prop_boolFormIsWideFormat = False
frmX.prop_strLinkProcedureToRun = "mod_Link_UserToGroup"
frmX.ShowDialog()
Fill_Grid_UsersGroups()
Closing
The above example shows a use for .NET reflection for searching and invoking methods in a certain module during runtime, with the method name being a variable. There are other useful methods besides GetMethod – such as GetEvent, but I’ll leave those up to you. My hope is that someone facing a similar issue will find some answers by looking at my example. Please post any relevant questions, and I’ll work to answer them. Thanks for reading!