471,305 Members | 1,247 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,305 software developers and data experts.

Invoke member of Userdefined Type

Hello all,

I'm hoping that someone could help me with this bit of code. I am
using reflection to dynamically call a method within an HttpHandler.
When a method returns a user defined type that implements a certain
interface, I want to call that interfaces method. The problem is that
the local varaible holding the user defined type is declared an object.
The compiler will accept the invocation of the interface method on that
object. I have a feeling that I may be getting over my head a little
bit on this one. Any hekp would be greatly appreciated. Code follows:

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Web;
using System.Reflection;
using PJC.PitchBook;
using PJC.PitchBook.Classes;
using PJC.PitchBook.Data;
using PJC.PitchBook.Web.UI.Ajax;

namespace PJC.PitchBook.Web.HttpHandlers {

public class ServerMethod:IHttpHandler {
HttpContext _context;

HttpRequest Request {
get {return _context.Request;}
}
HttpResponse Response {
get {return _context.Response;}
}
HttpContext Context {
get {return _context;}
set {_context = value;}
}
public void ProcessRequest(HttpContext context) {
Context = context;
NameValueCollection qs = Request.QueryString;
AJAXHandlerRequestStruct _values;
int i,j;
int countParams=qs.Count-1; //Will use this number later
if (countParams > -1) { //Meaning there is at least 1 (function
name) at qs[0]
_values = new AJAXHandlerRequestStruct();
_values.Args = new ArrayList();
_values.Method=qs[0]; //Function name here
for (i=1;i<countParams;i++) _values.Args.Add(qs[qs.GetKey(i)]);
//If any parameters, pick them up here
} else {
serverResponse(204);
return;
}

MethodInfo[] myMethods =
Assembly.GetExecutingAssembly().GetType("PJC.Pitch Book.Web.HttpHandlers.ServerMethod").GetMethods();
MethodInfo theMethod;

//Get the method that matches in name and number of parameters
for (i=0;i<myMethods.Length;i++) {
if ((myMethods[i].Name==_values.Method) &&
(myMethods[i].GetParameters().Length==countParams)) { //This is it!
theMethod=myMethods[i];
Object[] args;
try {
ParameterInfo[] _params = theMethod.GetParameters();
int paramCount = _params.Length;
args = new Object[paramCount];

//Convert argument value to type specified by parameterInfo
object
for (j=0;j<paramCount;j++) args[j] =
Convert.ChangeType(_values.Args[j],_params[j].ParameterType);
Type RTYPE = theMethod.ReturnType;
object myResult = theMethod.Invoke(this,args);

// Test to see if return type implements interface
if (RTYPE.GetInterface("ToAJAX",false) != null) {
serverResponse(myResult.ToAJAX(true));
} else {
string[] myVals = new string[2];
myVals[0] = myResult.ToString();
myVals[1] = string.Empty;
serverResponse(new AJAXHandlerResponseStruct(myVals));
}

} catch (Exception) {
serverResponse(204);
break;
}
break;
}
serverResponse(204);
break;
}
return;
}
private void serverResponse (AJAXHandlerResponseStruct response) {
Response.StatusCode = 200;
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.ContentType = "text/html";
Response.AppendHeader("X-JSON", response.JSON);
Response.AppendHeader("Content-Length",
response.HTML.Length.ToString());
Response.Write(response.HTML);
Response.Flush();
Response.Close();
}
private void serverResponse (int responseCode) {
Response.StatusCode = responseCode;
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.ContentType = "text/html";
Response.AppendHeader("X-JSON", "null");
Response.AppendHeader("Content-Length", "0");
Response.Write(string.Empty);
Response.Flush();
Response.Close();
}
public bool IsReusable {
get { return true; }
}

#region Server Methods
public PJC.PitchBook.Web.UI.Ajax.PJCSectionCollection
getSectionCollection() {
return new PJC.PitchBook.Web.UI.Ajax.PJCSectionCollection();
}
// public AJAXHandlerResponseStruct
getFilteredSectionCollection(UserLevel DisplayLevel, int UserID) {
// return new
PJC.PitchBook.Web.UI.Ajax.PJCSectionCollection(Dis playLevel,
UserID).Items;
// }
// public AJAXHandlerResponseStruct
getSearchResultsSectionCollection(UserLevel DisplayLevel, int UserID,
string SearchString) {
// return new
PJC.PitchBook.Web.UI.Ajax.PJCSectionCollection(Dis playLevel, UserID,
SearchString).Items;
// }
// public AJAXHandlerResponseStruct Expand(int id) {
// return new PJC.PitchBook.Web.UI.Ajax.PJCSection(id).Items;
// }
// public AJAXHandlerResponseStruct getCanvasCollection(int
CollectionID) {
// return new
PJC.PitchBook.Web.UI.Ajax.PJCCollection(Collection ID).Items;
// }
// public AJAXHandlerResponseStruct CollectionHasVariables(int
CollectionID) {
// PJCUser theUser = (PJCUser)Context.Session["User"];
// PJC.PitchBook.Data.PJCCollectionData _data = new
PJC.PitchBook.Data.PJCCollectionData(CollectionID) ;
// return (_data.PageVariableIDs.Count > 0 & theUser.UserID != 0);
// }
#endregion
}
}

Sorry about the crappy formatting.

-Tony

Feb 6 '06 #1
4 1915
> When a method returns a user defined type that implements a certain
interface, I want to call that interfaces method.The problem is that
the local varaible holding the user defined type is declared an object.
The compiler will accept the invocation of the interface method on that
object.

When you call the method using reflection (MethodInfo.Invoke in your
snippet), only the runtime-type matters. If you want to call the
interface methods, use Activator.CreateInstance then cast the return
value to that interface.

Hope that helps,
Thi

Feb 7 '06 #2
Thanks for the quick reply. Let me get this straight. If I can
determine the return type implements an interface, I can cast the
returned instance to the interface type, then call the interfaces
methods? I am sorry, I'm not at work and I see there are some errors in
the snippet I posted. Upen further review:

//This just creates an instance of the ReturnType of the method, using
the args[] for the method in the class contructor...This isn't the
intent.
Type RTYPE = theMethod.ReturnType;
if (RTYPE.GetInterface("IAJAXResponse",false) != null) {

serverResponse(((IAJAXResponse)Activator.CreateIns tance(RTYPE,args)).ToAJAX(true));
} else {...}

//Would this work?
Type RTYPE = theMethod.ReturnType;
object myResult = theMethod.Invoke(this,args);
// Test to see if return type implements interface
if (RTYPE.GetInterface("IAJAXResponse",false) != null) {
serverResponse(((IAJAXResponse)myResult).ToAJAX(tr ue));
} else {...}

-Tony

Feb 7 '06 #3
In this case, the call of CreateInstance is not necessary because you
already had the instance. So you could simply cast myResult to the
interface and call its ToAJAX method:
if (myResult is IAJAXResponse)
serverResponse( ((IAJAXResponse) myResult).ToAJAX(true));

That requires IJAXResponse to be known at compile time (that is, you
added a reference to it the DLL containing it). Otherwise, you could
call:
RTYPE.Invoke("ToAJAX", BindingFlags.InvokeMethod, null, myResult, new
object[] {true});

Thi

Feb 7 '06 #4
That worked perfectly and makes sense now. Thanks Thi.

-Tony

Feb 7 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Daniel Lidström | last post: by
13 posts views Thread by Christian Westerlund | last post: by
14 posts views Thread by gurry | last post: by
16 posts views Thread by recover | last post: by
3 posts views Thread by =?Utf-8?B?Sm9l?= | last post: by
reply views Thread by =?Utf-8?B?a3Jpc2huYQ==?= | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.