Delegates will be the end of me

T

Todd

I am desperately trying to figure out the following problem,
simplified for discussion.

I have a WinForm with a button, textbox, and datagrid. When I click
the button, I want to execute the method defined in the textbox, which
must return a dataset, and pass this dataset to the datasource of my
datagrid. Delegates and/or Reflection seem to be the natural way to
accomplish this.

My "Data tier" resides in another assembly which is referenced in my
WinForms project. I have in that assembly the following class
definition:

namespace Apex.Data
{
public class Class1
{
private Class1(){}

public static DataSet GetDataSet()
{
//return my dataset here...
}
}
}



So, in my attempts to figure this out, I've created the following
delegate and event handler for my button's click event:



public delegate DataSet DataProvider();

private void button1_Click(object sender, System.EventArgs e)
{
//1. manual binding
//this.dataGrid1.DataSource =
Apex.Data.Class1.GetDataSet().Tables[0];

//2. explicitly defined delegate
//DataProvider method = new
DataProvider(Apex.Data.Class1.GetDataSet);
//DataSet ds = method();
//this.dataGrid1.DataSource = ds.Tables[0];

//3. dynamically defined delegate
string functionName = this.textBox1.Text;
string className = functionName.Substring(0,functionName.LastIndexOf("."));
string methodName =
functionName.Substring(functionName.LastIndexOf(".")+1);

DataProvider method =
(DataProvider)System.Delegate.CreateDelegate(typeof(DataProvider),
typeof(Apex.Data.Class1), functionName);
DataSet ds = method();
this.dataGrid1.DataSource = ds.Tables[0];
}



The results of these 3 attempts:

1. I was just making sure the dang static method itself works. It
does.
2. Define the delegate explicitly. No problem.
3. Create the delegate at runtime. NOT HAPPENING.

The problem with #3 appears to be that System.Type.GetType(className)
returns null. Why does it return null? Is there a better approach to
this whole problem? Thanks in advance.
 
K

Ken Kolda

The example 3 that you showed is using typeof(Apex.Data.Class1) instead of
GetType(className). Can I assume that the example #3 that you show works?

Now, if you replace the typeof(...) with GetType(className), the reason this
is likely not working is that you're not providing the necessary assembly
information so the class loader can find the type. Here's an excerpt from
the MSDN documentation on GetType(string typeName):

"typeName can be a simple type name, a type name that includes a namespace,
or a complex name that includes an assembly name specification.
If typeName includes only the name of the Type, this method searches in the
calling object's assembly, then in the mscorlib.dll assembly. If typeName is
fully qualified with the partial or complete assembly name, this method
searches in the specified assembly."

You need to provide a fully qualified class name, which looks like this:
MyNamespace.MyClass,MyAssembly.

Ken


Todd said:
I am desperately trying to figure out the following problem,
simplified for discussion.

I have a WinForm with a button, textbox, and datagrid. When I click
the button, I want to execute the method defined in the textbox, which
must return a dataset, and pass this dataset to the datasource of my
datagrid. Delegates and/or Reflection seem to be the natural way to
accomplish this.

My "Data tier" resides in another assembly which is referenced in my
WinForms project. I have in that assembly the following class
definition:

namespace Apex.Data
{
public class Class1
{
private Class1(){}

public static DataSet GetDataSet()
{
//return my dataset here...
}
}
}



So, in my attempts to figure this out, I've created the following
delegate and event handler for my button's click event:



public delegate DataSet DataProvider();

private void button1_Click(object sender, System.EventArgs e)
{
//1. manual binding
//this.dataGrid1.DataSource =
Apex.Data.Class1.GetDataSet().Tables[0];

//2. explicitly defined delegate
//DataProvider method = new
DataProvider(Apex.Data.Class1.GetDataSet);
//DataSet ds = method();
//this.dataGrid1.DataSource = ds.Tables[0];

//3. dynamically defined delegate
string functionName = this.textBox1.Text;
string className = functionName.Substring(0,functionName.LastIndexOf("."));
string methodName =
functionName.Substring(functionName.LastIndexOf(".")+1);

DataProvider method =
(DataProvider)System.Delegate.CreateDelegate(typeof(DataProvider),
typeof(Apex.Data.Class1), functionName);
DataSet ds = method();
this.dataGrid1.DataSource = ds.Tables[0];
}



The results of these 3 attempts:

1. I was just making sure the dang static method itself works. It
does.
2. Define the delegate explicitly. No problem.
3. Create the delegate at runtime. NOT HAPPENING.

The problem with #3 appears to be that System.Type.GetType(className)
returns null. Why does it return null? Is there a better approach to
this whole problem? Thanks in advance.
 
T

Todd

Thanks Ken!

That worked, especially after I got the method name correct in my
code! :~|

I put a second textbox on my form in which I enter the assembly name.
Here's the code now, which uses a different constructor for the
CreateDelegate() method than I was using before only because the IL is
slightly leaner with this code:

string functionName = this.textBox1.Text;
string className = functionName.Substring(0,functionName.LastIndexOf("."));
string methodName = functionName.Substring(functionName.LastIndexOf(".")+1);
string assemblyName = this.textBox2.Text;

DataSet ds = ((DataProvider)System.Delegate.CreateDelegate(typeof(DataProvider),
Assembly.Load(assemblyName).GetType(className).GetMethod(methodName)))();

this.dataGrid1.DataSource = ds.Tables[0];





Ken Kolda said:
The example 3 that you showed is using typeof(Apex.Data.Class1) instead of
GetType(className). Can I assume that the example #3 that you show works?

Now, if you replace the typeof(...) with GetType(className), the reason this
is likely not working is that you're not providing the necessary assembly
information so the class loader can find the type. Here's an excerpt from
the MSDN documentation on GetType(string typeName):

"typeName can be a simple type name, a type name that includes a namespace,
or a complex name that includes an assembly name specification.
If typeName includes only the name of the Type, this method searches in the
calling object's assembly, then in the mscorlib.dll assembly. If typeName is
fully qualified with the partial or complete assembly name, this method
searches in the specified assembly."

You need to provide a fully qualified class name, which looks like this:
MyNamespace.MyClass,MyAssembly.

Ken


Todd said:
I am desperately trying to figure out the following problem,
simplified for discussion.

I have a WinForm with a button, textbox, and datagrid. When I click
the button, I want to execute the method defined in the textbox, which
must return a dataset, and pass this dataset to the datasource of my
datagrid. Delegates and/or Reflection seem to be the natural way to
accomplish this.

My "Data tier" resides in another assembly which is referenced in my
WinForms project. I have in that assembly the following class
definition:

namespace Apex.Data
{
public class Class1
{
private Class1(){}

public static DataSet GetDataSet()
{
//return my dataset here...
}
}
}



So, in my attempts to figure this out, I've created the following
delegate and event handler for my button's click event:



public delegate DataSet DataProvider();

private void button1_Click(object sender, System.EventArgs e)
{
//1. manual binding
//this.dataGrid1.DataSource =
Apex.Data.Class1.GetDataSet().Tables[0];

//2. explicitly defined delegate
//DataProvider method = new
DataProvider(Apex.Data.Class1.GetDataSet);
//DataSet ds = method();
//this.dataGrid1.DataSource = ds.Tables[0];

//3. dynamically defined delegate
string functionName = this.textBox1.Text;
string className = functionName.Substring(0,functionName.LastIndexOf("."));
string methodName =
functionName.Substring(functionName.LastIndexOf(".")+1);

DataProvider method =
(DataProvider)System.Delegate.CreateDelegate(typeof(DataProvider),
typeof(Apex.Data.Class1), functionName);
DataSet ds = method();
this.dataGrid1.DataSource = ds.Tables[0];
}



The results of these 3 attempts:

1. I was just making sure the dang static method itself works. It
does.
2. Define the delegate explicitly. No problem.
3. Create the delegate at runtime. NOT HAPPENING.

The problem with #3 appears to be that System.Type.GetType(className)
returns null. Why does it return null? Is there a better approach to
this whole problem? Thanks in advance.
 

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