Friday, May 16, 2008

"Exception has been thrown by target of invocation" Error

You might face this error and wonder what happened. I had a similar situation today. The code was working fine and all of a sudden I got this error. I am not that kind of person who beleives very strongly that all errors are due to some bad coding, maybe by the developer or maybe thrown bt the tools used for development. Till now, whenever I have been involved in coding or debuging someone's problem , I have managed to at least find out where the issues have been and most of time solve it too. Anyway, so I started tracing my steps backwards and commenting recenlty changed codes. But still was not able to find exactly where the error is occuring.

Finally, during one my debug attempts, I happened to look at the exception object's inner exception and noticed the error was because of a new addition I had on the app.config file. I made the correction and the error was gone. BTW, the change I did was add a "configSections" tag at the end of the app.config file. If you add a "configSections" tag, it has be the first line after the "configuration" tag.

So to conclude, if you get this error ""Exception has been thrown by target of invocation"", look at the inner exceptions. Keep looking recursively into the inner exception's "inner exception" till you see "nothing" and hopefully you see the actual error message and correct the problem.

happy coding !!

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 !!