Tuesday, May 6, 2008

Public member 'OverRideMethod' on type 'ObjectHandle' not found. [Reflection - Access methods from class dynamically]

I had a hard time with this. Spend around 2-3 hours trying various options till i got a clue from one of the links on the internet.

I had a class library (dll) referenced in a windows project and all the classes in this dll is inherited from a base class. The baseclass is mustinherit and has mustoverride function. My plan was that this windows application would have a list of (dynamically maintained using a XML file in the windows application) classes and its methods that can be executed from this dll. Each of the class within this dll overrides the mustoverride function from the baseclass and does some actions. The reason for this design was to make a "plug and play" kind of application. So if i wanted to add a new functionality, i just need to add a new class to the dll, edit the XML file and the front-end will show this new functionality and it will execute it. There were many other functions that were specific to the project that need not be discussed here .. Anyway, this sounded very simple to me and i started with writing the code..

The first thing that came into my mind was whether i would have to use reflection. But the dll was referenced in the main windows project. So there was no need to load a assembly dynamically and i did not want to go with that approach. Then found from the help about Activator.CreateInstance which has a overloaded function which accepts 2 strings .. the assembly name and the class name .. this was what i wanted. So i wrote this

Dim lObject As Object
lObject = Activator.CreateInstance("Namespace.MyAssembly", "Derived Class Name")
lObject.OverRideMethod

But this kept giving an error on the line where it is executing overriden method.
Public member 'OverRideMethod' on type 'ObjectHandle' not found.

I was sure that the object was getting created because when i changed the assembly or the class name, it gave the error on that line. So what was the issue? I could not get any help in MSDN. So i started searching the net and luckily got a link which said that Activator.CreateInstance does not give a object in return, but returns a object handle. I checked MSDN and it said that it gave back a object. I aklso noticed now that the error I got mentioned that "... on type ObjectHandle not found" So I decided to give it a try.. So I changed the code to

Dim lHandle As System.Runtime.Remoting.ObjectHandle
lHandle = Activator.CreateInstance("Namespace.MyAssembly", "Derived Class Name")
lRulesObject = lHandle.Unwrap()
lRulesObject.OverRideMethod

Lo and behold, it worked !! ..

I also type cast my object to the baseclass so that I can now call the method from the baseclass directly.. So my final code was

Dim lHandle As System.Runtime.Remoting.ObjectHandle
Dim lRulesBase As MyBaseClass
Dim lRulesObject As Object

lHandle = Activator.CreateInstance("Namespace.MyAssembly", "Derived Class Name")
lRulesObject = lHandle.Unwrap()
'-- cast it to the base class
lRulesBase = DirectCast(lRulesObject, MyBaseClass)
'-- call the service method
lRulesBase.OverRideMethod()

I spend some time finding this out and i thought I will post this for others who might have similar issues.

Happy coding !!

1 comment: