// Author:
// Miguel de Icaza (miguel@ximian.com)
// Dietmar Maurer (dietmar@ximian.com)
-// Lluis Sanchez Gual (lsg@ctv.es)
+// Lluis Sanchez Gual (lluis@ideary.com)
//
// (C) Ximian, Inc. http://www.ximian.com
//
-//
-// FIXME: This is just a skeleton for practical purposes.
-//
using System;
using System.Runtime.Serialization;
{
IChannelInfo channel_info;
string uri;
- Type type;
+ IRemotingTypeInfo typeInfo;
+ IEnvoyInfo envoyInfo;
+ [NonSerialized] bool marshalledValue = false;
public ObjRef ()
{
// The ObjRef can only be constructed if the given mbr
// has already been marshalled using RemotingServices.Marshall
- this.uri = RemotingServices.GetObjectUri(mbr);
- this.type = type;
+ uri = RemotingServices.GetObjectUri(mbr);
+ typeInfo = new TypeInfo(type);
+
+ if (!typeInfo.CanCastTo(mbr.GetType(), mbr))
+ throw new RemotingException ("The server object type cannot be cast to the requested type " + type.FullName + ".");
channel_info = new ChannelInfoStore ();
}
protected ObjRef (SerializationInfo si, StreamingContext sc)
{
SerializationInfoEnumerator en = si.GetEnumerator();
+ // Info to serialize: uri, objrefFlags, typeInfo, envoyInfo, channelInfo
+
+ marshalledValue = false;
while (en.MoveNext ()) {
switch (en.Name) {
case "uri":
uri = (string)en.Value;
break;
- case "type":
- type = (Type)en.Value;
+ case "typeInfo":
+ typeInfo = (IRemotingTypeInfo)en.Value;
break;
case "channelInfo":
- type = (Type)en.Value;
+ channel_info = (IChannelInfo)en.Value;
+ break;
+ case "envoyInfo":
+ envoyInfo = (IEnvoyInfo)en.Value;
+ break;
+ case "fIsMarshalled":
+ marshalledValue = true;
+ break;
+ case "objrefFlags": // FIXME: do something with this
break;
default:
throw new NotSupportedException ();
[MonoTODO]
public virtual IRemotingTypeInfo TypeInfo {
get {
- throw new NotImplementedException ();
+ return typeInfo;
}
set {
- throw new NotImplementedException ();
+ typeInfo = value;
}
}
public virtual void GetObjectData (SerializationInfo si, StreamingContext sc)
{
- si.SetType (type);
-
- si.AddValue ("url", uri);
- si.AddValue ("type", type, typeof (Type));
+ si.SetType (GetType());
+ si.AddValue ("uri", uri);
+ si.AddValue ("typeInfo", typeInfo, typeof (IRemotingTypeInfo));
+ si.AddValue ("envoyInfo", envoyInfo, typeof (IEnvoyInfo));
si.AddValue ("channelInfo", channel_info, typeof(IChannelInfo));
+ si.AddValue ("objrefFlags", 0);
}
public virtual object GetRealObject (StreamingContext sc)
{
- return RemotingServices.GetRemoteObject(type, null, channel_info.ChannelData);
+ if (marshalledValue)
+ return RemotingServices.GetRemoteObject(Type.GetType(typeInfo.TypeName), null, channel_info.ChannelData, uri);
+ else
+ return this;
}
public bool IsFromThisAppDomain ()
//
// Authors:
// Dietmar Maurer (dietmar@ximian.com)
-// Lluis Sanchez Gual (lsg@ctv.es)
+// Lluis Sanchez Gual (lluis@ideary.com)
//
// (C) 2001 Ximian, Inc. http://www.ximian.com
//
public static object Connect (Type classToProxy, string url)
{
- return GetRemoteObject(classToProxy, url, null);
+ return GetRemoteObject(classToProxy, url, null, null);
}
public static object Connect (Type classToProxy, string url, object data)
{
- return GetRemoteObject (classToProxy, url, data);
+ return GetRemoteObject (classToProxy, url, data, null);
}
public static Type GetServerTypeForUri (string uri)
public static string GetObjectUri (MarshalByRefObject obj)
{
- if (IsTransparentProxy(obj))
+ Identity ident = GetObjectIdentity(obj);
+ if (ident != null) return ident.ObjectUri;
+ else return null;
+ }
+
+ public static object Unmarshal (ObjRef objref)
+ {
+ return Unmarshal(objref, false);
+ }
+
+ public static object Unmarshal (ObjRef objref, bool fRefine)
+ {
+ // FIXME: use type name when fRefine==true
+ Type requiredType = Type.GetType(objref.TypeInfo.TypeName);
+ return GetRemoteObject(requiredType, null, objref.ChannelInfo.ChannelData, objref.URI);
+ }
+
+ public static ObjRef Marshal (MarshalByRefObject obj)
+ {
+ return Marshal (obj, null, null);
+ }
+
+ public static ObjRef Marshal (MarshalByRefObject obj, string uri)
+ {
+ return Marshal (obj, uri, null);
+ }
+
+ public static ObjRef Marshal (MarshalByRefObject obj, string uri, Type requested_type)
+ {
+ if (IsTransparentProxy (obj))
{
- return GetRealProxy (obj).ObjectIdentity.ObjectUri;
+ RealProxy proxy = RemotingServices.GetRealProxy(obj);
+ if (proxy != null && proxy.ObjectIdentity != null)
+ {
+ if (uri != null)
+ throw new RemotingException ("It is not possible marshal a proxy of a remote object");
+
+ return proxy.ObjectIdentity.CreateObjRef(requested_type);
+ }
}
+
+ if (uri == null) uri = app_id + Environment.TickCount + "_" + next_id++;
+
+ // It creates the identity if not found
+ Identity identity = GetServerIdentity (obj, uri);
+
+ if (obj != identity.RealObject)
+ throw new RemotingException ("uri already in use, " + uri);
+ // already registered
+
+ return identity.CreateObjRef(requested_type);
+ }
+
+ public static RealProxy GetRealProxy (object proxy)
+ {
+ if (!IsTransparentProxy(proxy)) throw new RemotingException("Cannot get the real proxy from an object that is not a transparent proxy");
+ return (RealProxy)((TransparentProxy)proxy)._rp;
+ }
+
+ public static MethodBase GetMethodBaseFromMethodMessage(IMethodMessage msg)
+ {
+ Type type = Type.GetType(msg.TypeName);
+
+ if (msg.MethodSignature == null)
+ return type.GetMethod (msg.MethodName);
else
- return obj.ObjectIdentity.ObjectUri;
+ return type.GetMethod (msg.MethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, (Type[]) msg.MethodSignature, null);
+ }
+
+ public static void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
+ if (obj == null) throw new ArgumentNullException ("obj");
+
+ MarshalByRefObject mbr = (MarshalByRefObject)obj;
+
+ ObjRef oref;
+ Identity ident = GetObjectIdentity(mbr);
+
+ if (ident != null)
+ oref = ident.CreateObjRef(null);
+ else
+ oref = Marshal (mbr);
+
+ oref.GetObjectData (info, context);
+ }
+
+ public static ObjRef GetObjRefForProxy(MarshalByRefObject obj)
+ {
+ Identity ident = GetObjectIdentity(obj);
+ if (ident == null) return null;
+ else return ident.CreateObjRef(null);
+ }
+
+ [MonoTODO]
+ public static string GetSessionIdForMethodMessage(IMethodMessage msg)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public static bool IsMethodOverloaded(IMethodMessage msg)
+ {
+ Type type = msg.MethodBase.DeclaringType;
+ MemberInfo[] members = type.GetMember (msg.MethodName, MemberTypes.Method, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);\r
+ return members.Length > 1;\r
+ }
+
+ public static bool IsObjectOutOfAppDomain(object tp)
+ {
+ Identity ident = GetObjectIdentity((MarshalByRefObject)tp);
+ if (ident != null) return !ident.IsFromThisAppDomain;
+ else return false;
+ }
+
+ public static bool IsObjectOutOfContext(object tp)
+ {
+ Identity ident = GetObjectIdentity((MarshalByRefObject)tp);
+ if (ident != null) return ident.Context != System.Threading.Thread.CurrentContext;
+ else return false;
}
+
+ public static bool IsOneWay(MethodBase method)
+ {
+ object[] atts = method.GetCustomAttributes (typeof (OneWayAttribute), false);
+ return atts.Length > 0;
+ }
+
+ public static void SetObjectUriForMarshal(MarshalByRefObject obj, string uri)
+ {
+ if (IsTransparentProxy (obj)) throw new RemotingException ("SetObjectUriForMarshal method should only be called for MarshalByRefObjects that exist in the current AppDomain.");
+ Marshal (obj, uri);
+ }
+
+
+ #region Internal Methods
internal static MarshalByRefObject GetServerForUri (string uri)
{
}
}
- private static Identity GetClientIdentity(Type requiredType, string url, object channelData)
+ internal static Identity GetObjectIdentity (MarshalByRefObject obj)
+ {
+ if (IsTransparentProxy(obj))
+ return GetRealProxy (obj).ObjectIdentity;
+ else
+ return obj.ObjectIdentity;
+ }
+
+ private static Identity GetClientIdentity(Type requiredType, string url, object channelData, string remotedObjectUri)
{
// This method looks for an identity for the given url.
// If an identity is not found, it creates the identity and
IMessageSink sink = ChannelServices.CreateClientChannelSinkChain (url, channelData, out objectUri);
if (sink == null)
{
- string msg = String.Format ("Cannot create channel sink to connect to URL {0}.", url);
- throw new RemotingException (msg);
+ if (url != null) {
+ string msg = String.Format ("Cannot create channel sink to connect to URL {0}. An appropriate channel has probably not been registered.", url);
+ throw new RemotingException (msg);
+ }
+ else {
+ string msg = String.Format ("Cannot create channel sink to connect to the remote object. An appropriate channel has probably not been registered.", url);
+ throw new RemotingException (msg);
+ }
}
+ if (objectUri == null) objectUri = remotedObjectUri;
+
lock (uri_hash)
{
Identity identity = (Identity)uri_hash [objectUri];
identity.ClientSink = sink;
RemotingProxy proxy = new RemotingProxy (requiredType, identity);
+
identity.RealObject = proxy.GetTransparentProxy();
// Registers the identity
}
}
- internal static object GetRemoteObject(Type requiredType, string url, object channelData)
+ internal static object GetRemoteObject(Type requiredType, string url, object channelData, string remotedObjectUri)
{
- Identity id = GetClientIdentity(requiredType, url, channelData);
+ Identity id = GetClientIdentity(requiredType, url, channelData, remotedObjectUri);
return id.RealObject;
}
-
- public static object Unmarshal (ObjRef objref)
- {
- return Unmarshal(objref, false);
- }
-
- public static object Unmarshal (ObjRef objref, bool fRefine)
- {
- // FIXME: use type name when fRefine==true
- Type requiredType = Type.GetType(objref.TypeInfo.TypeName);
- return GetRemoteObject(requiredType, null, objref.ChannelInfo.ChannelData);
- }
- public static ObjRef Marshal (MarshalByRefObject obj)
- {
- return Marshal (obj, null, null);
- }
+ #endregion
- public static ObjRef Marshal (MarshalByRefObject obj, string uri)
- {
- return Marshal (obj, uri, null);
- }
-
- public static ObjRef Marshal (MarshalByRefObject obj, string uri, Type requested_type)
- {
- if (IsTransparentProxy (obj))
- {
- RealProxy proxy = RemotingServices.GetRealProxy(obj);
- if (proxy != null && proxy.ObjectIdentity != null)
- {
- if (uri != null)
- throw new RemotingException ("It is not possible marshal a proxy of a remote object");
-
- return proxy.ObjectIdentity.CreateObjRef(requested_type);
- }
- }
-
- if (uri == null) uri = app_id + Environment.TickCount + "_" + next_id++;
-
- // It creates the identity if not found
- Identity identity = GetServerIdentity (obj, uri);
-
- if (obj != identity.RealObject)
- throw new RemotingException ("uri already in use, " + uri);
- // already registered
-
- return identity.CreateObjRef(requested_type);
- }
-
- public static RealProxy GetRealProxy (object proxy)
- {
- if (!IsTransparentProxy(proxy)) throw new RemotingException("Cannot get the real proxy from an object that is not a transparent proxy");
- return (RealProxy)((TransparentProxy)proxy)._rp;
- }
}
+
}
--- /dev/null
+//
+// System.Runtime.Remoting.TypeInfo.cs
+//
+// Author: Lluis Sanchez Gual (lluis@ideary.com)
+//
+// (C) 2003, Lluis Sanchez Gual
+//\r
+\r
+using System;\r
+\r
+namespace System.Runtime.Remoting\r
+{\r
+ [Serializable]\r
+ internal class TypeInfo : IRemotingTypeInfo\r
+ {\r
+ string serverType;\r
+ string[] serverHierarchy;\r
+ string[] interfacesImplemented;\r
+\r
+ public TypeInfo(Type type)\r
+ {\r
+ serverType = type.AssemblyQualifiedName;\r
+\r
+ // base class info\r
+\r
+ int baseCount = 0;\r
+ Type baseType = type.BaseType;\r
+ while (baseType != typeof (MarshalByRefObject) && baseType != typeof(object))\r
+ {\r
+ baseType = baseType.BaseType;\r
+ baseCount++;\r
+ }\r
+\r
+ serverHierarchy = new string[baseCount];\r
+ baseType = type.BaseType;\r
+ for (int n=0; n<baseCount; n++) \r
+ {\r
+ serverHierarchy[n] = baseType.AssemblyQualifiedName;\r
+ baseType = baseType.BaseType;\r
+ }\r
+\r
+ // Interfaces info\r
+\r
+ Type[] interfaces = type.GetInterfaces();\r
+ interfacesImplemented = new string[interfaces.Length];\r
+ for (int n=0; n<interfaces.Length; n++)\r
+ interfacesImplemented[n] = interfaces[n].AssemblyQualifiedName;\r
+ }\r
+\r
+ public string TypeName \r
+ {\r
+ get { return serverType; }\r
+ set { serverType = value; }\r
+ }\r
+\r
+ public bool CanCastTo (Type fromType, object o)\r
+ {\r
+ if (fromType == typeof (object)) return true;\r
+ if (fromType == typeof (MarshalByRefObject)) return true;\r
+\r
+ string fromName = fromType.AssemblyQualifiedName;\r
+\r
+ // Find the type comparing the name of the type and the name of the assembly,\r
+ // excluding version and other assembly info\r
+\r
+ int i = fromName.IndexOf (",");\r
+ if (i != -1) i = fromName.IndexOf (",", i+1);\r
+ if (i != -1) fromName = fromName.Substring (0,i+1);\r
+ else fromName += ",";\r
+\r
+ if ( (serverType + ",").StartsWith (fromName)) return true;\r
+\r
+ foreach (string basec in serverHierarchy)\r
+ if ( (basec + ",").StartsWith (fromName)) return true;\r
+\r
+ foreach (string basec in interfacesImplemented)\r
+ if ( (basec + ",").StartsWith (fromName)) return true;\r
+\r
+ return false;\r
+ }\r
+ }\r
+}\r