Generic method support issues for. NET Dynamic agents

Source: Internet
Author: User

has been working on the high-speed service framework of the. NET platform recently. One of the problems that has been bothering me: A service proxy created through dynamic proxy realproxy does not support generic method calls. Like what:

Interface declaration:

public interface Imetedataservice
{
String getdata<t> (T p);

String getdatawithhsf<t> (T p);
}

Interface implementation:

public class Eventmetadataservice:imetedataservice
{
public string getdata<t> (T p)
{
JavaScriptSerializer ser = new JavaScriptSerializer ();
Return ser. Serialize (P);
}

public string getdatawithhsf<t> (T p)
{
JavaScriptSerializer ser = new JavaScriptSerializer ();
String data = Ser. Serialize (P);

String getdata = Hsfservice.proxy<imetedataservice> (). Getdata<string> (DateTime.Now.ToLongTimeString ());
return GetData + "" + data;

}
}

Eventmetadataservice is deployed to the container of HSF. At the consumer end of the HSF, the calling code is as follows. This code executes with an exception: cannot perform late-bound operation on a type or method that is containsgenericparameters true

EventData dd = new EventData ();
Dd.id = Guid.NewGuid (). ToString ();
Dd. Code = "Good boy";
Dd. Names = data;
list<eventdata> res = new list<eventdata> ();
Res. ADD (DD);

var result = hsfservice.proxy<imetedataservice> (). Getdata<list<eventdata>> (RES);

In Hsfservice, the container service of HSF is called remotely through a dynamic proxy. Overloaded with the RealProxy, its core code is as follows:

public override IMessage Invoke (IMessage msg)
{

DateTime start = DateTime.Now;
Remoteinvokemessage requestmessage = null;
var message = msg as IMethodCallMessage;
if (message = = NULL)
{
return null;
}

Try
{
Requestmessage = newRemoteinvokemessage
{
Serviceclassname = typeof (Tproxy). FullName,
MethodName = message. MethodName,
Parameters = message. Inargs,
Version = This._serviceversion,
Properties = new system.collections.generic.dictionary<string, string> (stringcomparer.ordinalignorecase)
};

                var Responsemessage = Tcpclient.sendmessageandwaitforresponse (requestmessage) as Remoteinvokereturnmessage;
                if ( Responsemessage = = null)
                 {
                     return null;
               }

if (responsemessage.remoteexception! = null)
{
return new ReturnMessage (responsemessage.remoteexception, message);

}
Else
{
return new ReturnMessage (responsemessage.returnvalue, NULL, 0, message. LogicalCallContext, message);
}
}
catch (Exception ex)
{
return new ReturnMessage (ex, message);
}
}
}

To resolve the above exception, the RealProxy invoke code is modified and the properties of the record generic method are added to the remoteinvokemessage :

Public string[] Generictypes {get; set;}

The code for the Invoke method is updated as follows:

public override IMessage Invoke (IMessage msg)
{

DateTime start = DateTime.Now;
Remoteinvokemessage requestmessage = null;
var message = msg as IMethodCallMessage;
if (message = = NULL)
{
return null;
}

Try
{
Requestmessage = new Remoteinvokemessage
{
Serviceclassname = typeof (Tproxy). FullName,
MethodName = message. MethodName,
Parameters = message. Inargs,
Version = This._serviceversion,
Properties = new system.collections.generic.dictionary<string, string> (stringcomparer.ordinalignorecase)
};

if (message. methodbase!= NULL && message. Methodbase.isgenericmethod)
{
VAR tps= message. Methodbase.getgenericarguments ();
if (TPS! = null)
{
list<string> strtypes = new list<string> ();

foreach (var item in TPS)
{
Strtypes.add (Jsonconvert.serializeobject (item));
}

                         requestmessage.generictypes = Strtypes.toarray ();
                    }
               }

                var Responsemessage = Tcpclient.sendmessageandwaitforresponse (requestmessage) as Remoteinvokereturnmessage;
                if ( Responsemessage = = null)
                 {
                     return null;
               }

if (responsemessage.remoteexception! = null)
{
return new ReturnMessage (responsemessage.remoteexception, message);

}
Else
{
return new ReturnMessage (responsemessage.returnvalue, NULL, 0, message. LogicalCallContext, message);
}
}
catch (Exception ex)
{
return new ReturnMessage (ex, message);
}
}
}

The above tag code, mainly extracts the type of the generic method. As long as the type is passed to the HSF container, the associated type can be reflected, and when the method is called, the generic type is set by the MakeGenericMethod method, which resolves the exception " You cannot perform a late-bound operation on a type or method that is containsgenericparameters true . "

MethodInfo m = null;
if (Methodmap.containskey (methodName) = = True)
{
if (Methodmap.trygetvalue (MethodName, out m) = = False)
m = Internalgetmethod (TypeName, MethodName, M, Arg);
}
Else
m = Internalgetmethod (TypeName, MethodName, M, Arg);

if (M.isgenericmethod)
{
list<type> Typs = new list<type> ();
if (message. Generictypes = null)
{
foreach (string item in message. Generictypes)
{
Typs. ADD (Getdatatype (item));
}
}
m = M.makegenericmethod (Typs. ToArray ());
}

By the way, when HSF container gets the type of the generic method, it needs to convert to type Object, and here are a lot of questions and tricks to post my solution.

Private Type Getdatatype (string item)
{
String asmname = String. Empty;
String tname = String. Empty;

var CItem = Item. Replace ("\" "," ");

Type result = Type.GetType (CItem, False, true);
if (result! = NULL)
return result;
if (result = = null)
result = Type.reflectiononlygettype (CItem, False, true);
if (result! = NULL)
return result;

throw new Hsfexception (Errorcode.invalideparam, "Cannot find type:" + Item);

}

Make sure that the assembly that corresponds to the type has already been loaded.

Wei Liang 2016-2-1

Generic method support issues for. NET Dynamic agents

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.