using System.Collections;
using System.Reflection;
using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
namespace System.Runtime.Remoting.Messaging {
[Serializable] [CLSCompliant (false)]
+ [System.Runtime.InteropServices.ComVisible (true)]
public class MethodCall : IMethodCallMessage, IMethodMessage, IMessage, ISerializable, IInternalMessage, ISerializationRootObject
{
string _uri;
LogicalCallContext _callContext;
ArgInfo _inArgInfo;
Identity _targetIdentity;
+ Type[] _genericArguments;
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)
Init();
ResolveMethod();
}
-
+#if FEATURE_REMOTING
+ internal MethodCall (Object handlerObject, BinaryMethodCallMessage smuggledMsg)
+ {
+ if (handlerObject != null)
+ {
+ _uri = handlerObject as String;
+ if (_uri == null)
+ {
+ // This must be the tranparent proxy
+ MarshalByRefObject mbr = handlerObject as MarshalByRefObject;
+ if (mbr != null)
+ {
+ throw new NotImplementedException ("MarshalByRefObject.GetIdentity");
+/*
+ bool fServer;
+ srvID = MarshalByRefObject.GetIdentity(mbr, out fServer) as ServerIdentity;
+ uri = srvID.URI;
+*/
+ }
+ }
+ }
+
+ _typeName = smuggledMsg.TypeName;
+ _methodName = smuggledMsg.MethodName;
+ _methodSignature = (Type[])smuggledMsg.MethodSignature;
+ _args = smuggledMsg.Args;
+ _genericArguments = smuggledMsg.InstantiationArgs;
+ _callContext = smuggledMsg.LogicalCallContext;
+
+ ResolveMethod();
+
+ if (smuggledMsg.HasProperties)
+ smuggledMsg.PopulateMessageProperties(Properties);
+ }
+#endif
internal MethodCall ()
{
}
_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;
+ case "__GenericArguments" : _genericArguments = (Type[]) value; return;
default: Properties[key] = value; return;
}
}
info.AddValue ("__Args", _args);
info.AddValue ("__CallContext", _callContext);
info.AddValue ("__Uri", _uri);
+ info.AddValue ("__GenericArguments", _genericArguments);
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 {
internal virtual void InitDictionary()
{
- MethodCallDictionary props = new MethodCallDictionary (this);
+ var props = new MCMDictionary (this);
ExternalProperties = props;
InternalProperties = props.GetInternalProperties();
}
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);
+ }
+
+
+ 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);
}
- _methodBase = RemotingServices.GetMethodBaseFromMethodMessage (this);
}
- 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)
+ {
+ int p = aqname.IndexOf ("]]");
+ int i = aqname.IndexOf(',', p == -1 ? 0 : p + 2);
+ 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; }
}
- public override string ToString ()
+ bool IInternalMessage.HasProperties()
{
- string s = _typeName.Split(',')[0] + "." + _methodName + " (";
- if (_args != null)
- {
- for (int n=0; n<_args.Length; n++)
- {
- if (n>0) s+= ", ";
- if (_args[n] != null) s += _args[n].GetType().Name + " ";
- s += GetArgName (n);
- if (_args[n] != null) s += " = {" + _args[n] + "}";
- else s+=" = {null}";
- }
+ return (ExternalProperties != null) || (InternalProperties != null);
+ }
+
+ Type[] GenericArguments {
+ get {
+ if (_genericArguments != null)
+ return _genericArguments;
+
+ return _genericArguments = MethodBase.GetGenericArguments ();
}
- s += ")";
- return s;
}
}
}