namespace System.Runtime.Remoting.Messaging {
[Serializable] [CLSCompliant (false)]
+#if NET_2_0
+ [System.Runtime.InteropServices.ComVisible (true)]
+#endif
public class MethodCall : IMethodCallMessage, IMethodMessage, IMessage, ISerializable, IInternalMessage, ISerializationRootObject
{
string _uri;
LogicalCallContext _callContext;
ArgInfo _inArgInfo;
Identity _targetIdentity;
+#if NET_2_0
+ Type[] _genericArguments;
+#endif
protected IDictionary ExternalProperties;
protected IDictionary InternalProperties;
- public MethodCall (Header [] headers)
+ public MethodCall (Header [] h1)
{
Init();
- if (headers == null || headers.Length == 0) return;
+ if (h1 == null || h1.Length == 0) return;
- foreach (Header header in headers)
+ foreach (Header header in h1)
InitMethodProperty (header.Name, header.Value);
ResolveMethod ();
if (_callContext == null)
_callContext = new LogicalCallContext ();
- _methodBase = MethodBase.GetMethodFromHandle (msg.MethodHandle);
+ _methodBase = msg.GetMethod ();
+
Init();
if (msg.PropertiesCount > 0)
_methodSignature = (Type[]) call.MethodSignature;
_methodBase = call.MethodBase;
_callContext = call.LogicalCallContext;
-
Init();
}
case "__Args" : _args = (object[]) value; return;
case "__CallContext" : _callContext = (LogicalCallContext) value; return;
case "__Uri" : _uri = (string) value; return;
+#if NET_2_0
+ case "__GenericArguments" : _genericArguments = (Type[]) value; return;
+#endif
default: Properties[key] = value; return;
}
}
info.AddValue ("__Args", _args);
info.AddValue ("__CallContext", _callContext);
info.AddValue ("__Uri", _uri);
+#if NET_2_0
+ info.AddValue ("__GenericArguments", _genericArguments);
+#endif
if (InternalProperties != null) {
foreach (DictionaryEntry entry in InternalProperties)
}
public LogicalCallContext LogicalCallContext {
- get { return _callContext; }
+ get {
+ if (_callContext == null)
+ _callContext = new LogicalCallContext ();
+ return _callContext;
+ }
}
public MethodBase MethodBase {
set { _uri = value; }
}
+ string IInternalMessage.Uri {
+ get { return Uri; }
+ set { Uri = value; }
+ }
+
public object GetArg (int argNum)
{
return _args[argNum];
if (_uri != null)
{
Type type = RemotingServices.GetServerTypeForUri (_uri);
- if (type == null) throw new RemotingException ("Requested service not found. No receiver for uri " + _uri);
-
- if (CanCastTo (_typeName, type)) {
- _methodBase = RemotingServices.GetMethodBaseFromName (type, _methodName, _methodSignature);
- return;
+ if (type == null) {
+ string sname = _typeName != null ? " (" + _typeName + ")" : "";
+ throw new RemotingException ("Requested service not found" + sname + ". No receiver for uri " + _uri);
}
- else
+
+ Type requestType = CastTo (_typeName, type);
+ if (requestType == null)
throw new RemotingException ("Cannot cast from client type '" + _typeName + "' to server type '" + type.FullName + "'");
+
+ // Look for the method in the requested type. The method signature is provided
+ // only if the method is overloaded in the requested type.
+ _methodBase = RemotingServices.GetMethodBaseFromName (requestType, _methodName, _methodSignature);
+
+ if (_methodBase == null)
+ throw new RemotingException ("Method " + _methodName + " not found in " + requestType);
+
+ // If the method is implemented in an interface, look for the method implementation.
+ // It can't be done in the previous GetMethodBaseFromName call because at that point we
+ // may not yet have the method signature.
+ if (requestType != type && requestType.IsInterface && !type.IsInterface) {
+ _methodBase = RemotingServices.GetVirtualMethod (type, _methodBase);
+ if (_methodBase == null)
+ throw new RemotingException ("Method " + _methodName + " not found in " + type);
+ }
+
+ } else {
+ _methodBase = RemotingServices.GetMethodBaseFromMethodMessage (this);
+ if (_methodBase == null) throw new RemotingException ("Method " + _methodName + " not found in " + TypeName);
}
- _methodBase = RemotingServices.GetMethodBaseFromMethodMessage (this);
+
+
+#if NET_2_0
+ if (_methodBase.IsGenericMethod && _methodBase.ContainsGenericParameters) {
+ if (GenericArguments == null)
+ throw new RemotingException ("The remoting infrastructure does not support open generic methods.");
+ _methodBase = ((MethodInfo) _methodBase).MakeGenericMethod (GenericArguments);
+ }
+#endif
}
- bool CanCastTo (string clientType, Type serverType)
+ Type CastTo (string clientType, Type serverType)
{
- int i = clientType.IndexOf(',');
- if (i != -1) clientType = clientType.Substring (0,i).Trim();
-
- if (clientType == serverType.FullName) return true;
+ clientType = GetTypeNameFromAssemblyQualifiedName (clientType);
+ if (clientType == serverType.FullName) return serverType;
// base class hierarchy
Type baseType = serverType.BaseType;
while (baseType != null) {
- if (clientType == baseType.FullName) return true;
- baseType = baseType.BaseType;
- }
+ if (clientType == baseType.FullName) return baseType;
+ baseType = baseType.BaseType;
+ }
// Implemented interfaces
Type[] interfaces = serverType.GetInterfaces();
foreach (Type itype in interfaces)
- if (clientType == itype.FullName) return true;
+ if (clientType == itype.FullName) return itype;
- return false;
+ return null;
+ }
+
+ static string GetTypeNameFromAssemblyQualifiedName (string aqname)
+ {
+#if NET_2_0
+ int p = aqname.IndexOf ("]]");
+ int i = aqname.IndexOf(',', p == -1 ? 0 : p + 2);
+#else
+ int i = aqname.IndexOf(',');
+#endif
+ if (i != -1) aqname = aqname.Substring (0, i).Trim ();
+ return aqname;
}
[MonoTODO]
- public void RootSetObjectData (SerializationInfo info, StreamingContext context)
+ public void RootSetObjectData (SerializationInfo info, StreamingContext ctx)
{
throw new NotImplementedException ();
}
set { _targetIdentity = value; }
}
+#if !NET_2_0
public override string ToString ()
{
string s = _typeName.Split(',')[0] + "." + _methodName + " (";
s += ")";
return s;
}
+#endif
+
+#if NET_2_0
+ Type[] GenericArguments {
+ get {
+ if (_genericArguments != null)
+ return _genericArguments;
+
+ return _genericArguments = MethodBase.GetGenericArguments ();
+ }
+ }
+#endif
}
}