Beginner question about Reflection & code snippet.

M

Mike Malter

I am just starting to work with reflection and I want to create a log that saves relevant information if a method call fails so I
can call that method again later using reflection.

I am experimenting a bit with what I need to do this and have the following code snippet. But first if I pass the assembly name and
type to Activator.CreateInstance() it always fails. However if I walk my assembly and get a type value, the call to
Activator.CreateInstance() will always succeed.

My next question, is why can't I cast the return value from the Invoke() call to a DataSet. I thought it returned an object. Am I
missing something? The test method returns a DataSet.

Finally, I got some advice to use Type.InvokeMember() in this forum, but I had to unwrap the return and then needed to use typed
values to complete the call and I want to be able to build this entirely from strings from a database.

If my approach is way off, could someone please point me in the right direction?

Thanks. My code snippet is below.

MethodInfo myMethodEX = null;
Type myTypeEX = null;
Assembly assembly1 = Assembly.Load( "Ripple.Home.BusinessLayer" );
Type[] types = assembly1.GetTypes();
foreach( Type definedType in types )
{
sClass = definedType.Name;
if ( sClass == "Role" )
{
myTypeEX = definedType;
MethodInfo[] myMethod = definedType.GetMethods();
foreach( MethodInfo nextMethod in myMethod )
{
sMethod = nextMethod.Name;
if ( sMethod == "ListAll" )
{
myMethodEX = nextMethod;
break;
}
}
}
if ( sClass == "Role" )
{
break;
}
}

// This always succeeds
Object obj = Activator.CreateInstance( myTypeEX );

// This ALWAYS Fails
// Object obj = Activator.CreateInstance( "Ripple.Home.BusinessLayer", "Role" );

// The cast fails. How do I get my return value?
DataSet ds = (DataSet) myMethodEX.Invoke( obj, null );
 
M

Mike Malter

Jeffrey,

Thanks for your insight. My problem with Activator.CreateInstance() was that I was not using the full name in the second parameter.

I have an additional question that I could use your insight into. My approach now involves walking an entire assembly to get a
MethodInfo variable to do an Invoke() on. Is there a better, or more efficient way to use reflection to call a specific method in
an assembly if you already know the assembly name, the type and the method? I will be storing these values as strings in a database
log. Someone told me to use Type.InvokeMember(). How does that figure in to all of this?

Finally, if this is the best way to do this, can you give me a small example of how to format the parameter[] for the second
parameter of Invoke()? I will be wanting to call methods with parameters eventually.

Thanks.

Mike Malter


Jeffrey Tan said:
Hi Mike,

The Activator.CreateInstance(assemblyname,typename) function return
ObjectHandle type which wrapped the
object type.
So you should use UnWrap() method to get the object that was wrapped.
Also, I did not get any error on casting object to dataset.

Sample code listed below:

using System;
using System.Reflection;
using System.Runtime.Remoting ;
using System.Data ;

namespace reflectiontest
{
public class Role
{
public DataSet ListAll()
{
Console.WriteLine ("Role.ListAll()");
return new DataSet ();
}
}
class Class1
{

[STAThread]
static void Main(string[] args)
{
try
{
string sClass;
string sMethod;
MethodInfo myMethodEX = null;
Type myTypeEX = null;
Assembly assembly1 = Assembly.Load( "reflectiontest" );
Type[] types = assembly1.GetTypes();
foreach( Type definedType in types )
{
sClass = definedType.Name;
if ( sClass == "Role" )
{
myTypeEX = definedType;
MethodInfo[] myMethod = definedType.GetMethods();
foreach( MethodInfo nextMethod in myMethod )
{
sMethod = nextMethod.Name;
if ( sMethod == "ListAll" )
{
myMethodEX = nextMethod;
break;
}
}
}
if ( sClass == "Role" )
{
break;
}
}

//Object obj1= Activator.CreateInstance( myTypeEX );


ObjectHandle obj2 = Activator.CreateInstance(
"reflectiontest","reflectiontest.Role" );
Object obj3=obj2.Unwrap();

DataSet ds=(DataSet)myMethodEX.Invoke( obj3, null );//no error generate

}
catch(Exception e)
{
Console.WriteLine (e.Message );
}
Console.Read ();
}
}
}

If you have anything unclear, please feel free to let me know.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: "Mike Malter" <[email protected]>
| Subject: Beginner question about Reflection & code snippet.
| Date: Mon, 25 Aug 2003 17:30:06 -0700
| Lines: 55
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| Message-ID: <[email protected]>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: adsl-64-175-22-129.dsl.snfc21.pacbell.net 64.175.22.129
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP09.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:179292
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| I am just starting to work with reflection and I want to create a log
that saves relevant information if a method call fails so I
| can call that method again later using reflection.
|
| I am experimenting a bit with what I need to do this and have the
following code snippet. But first if I pass the assembly name and
| type to Activator.CreateInstance() it always fails. However if I walk my
assembly and get a type value, the call to
| Activator.CreateInstance() will always succeed.
|
| My next question, is why can't I cast the return value from the Invoke()
call to a DataSet. I thought it returned an object. Am I
| missing something? The test method returns a DataSet.
|
| Finally, I got some advice to use Type.InvokeMember() in this forum, but
I had to unwrap the return and then needed to use typed
| values to complete the call and I want to be able to build this entirely
from strings from a database.
|
| If my approach is way off, could someone please point me in the right
direction?
|
| Thanks. My code snippet is below.
|
| MethodInfo myMethodEX = null;
| Type myTypeEX = null;
| Assembly assembly1 = Assembly.Load( "Ripple.Home.BusinessLayer" );
| Type[] types = assembly1.GetTypes();
| foreach( Type definedType in types )
| {
| sClass = definedType.Name;
| if ( sClass == "Role" )
| {
| myTypeEX = definedType;
| MethodInfo[] myMethod = definedType.GetMethods();
| foreach( MethodInfo nextMethod in myMethod )
| {
| sMethod = nextMethod.Name;
| if ( sMethod == "ListAll" )
| {
| myMethodEX = nextMethod;
| break;
| }
| }
| }
| if ( sClass == "Role" )
| {
| break;
| }
| }
|
| // This always succeeds
| Object obj = Activator.CreateInstance( myTypeEX );
|
| // This ALWAYS Fails
| // Object obj = Activator.CreateInstance( "Ripple.Home.BusinessLayer",
"Role" );
|
| // The cast fails. How do I get my return value?
| DataSet ds = (DataSet) myMethodEX.Invoke( obj, null );
|
|
|
|
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top