2 // System.Runtime.Remoting.Proxies.RemotingProxy.cs
5 // Dietmar Maurer (dietmar@ximian.com)
6 // Lluis Sanchez Gual (lsg@ctv.es)
8 // (C) 2001 Ximian, Inc. http://www.ximian.com
12 using System.Reflection;
13 using System.Runtime.Remoting.Messaging;
14 using System.Runtime.Remoting.Activation;
15 using System.Runtime.Remoting.Channels;
16 using System.Runtime.Remoting.Contexts;
17 using System.Runtime.CompilerServices;
18 using System.Threading;
21 namespace System.Runtime.Remoting.Proxies
24 public class RemotingProxy : RealProxy
26 static MethodInfo _cache_GetTypeMethod = typeof(System.Object).GetMethod("GetType");
\r
27 static MethodInfo _cache_GetHashCodeMethod = typeof(System.Object).GetMethod("GetHashCode");
\r
30 string _activationUrl;
32 ConstructionCall _ctorCall;
34 internal RemotingProxy (Type type, ClientIdentity identity) : base (type, identity)
36 _sink = identity.ChannelSink;
37 _hasEnvoySink = false;
40 internal RemotingProxy (Type type, string activationUrl, object[] activationAttributes) : base (type)
42 _activationUrl = activationUrl;
43 _hasEnvoySink = false;
45 _ctorCall = ActivationServices.CreateConstructionCall (type, activationUrl, activationAttributes);
48 public override IMessage Invoke (IMessage request)
50 MonoMethodMessage mMsg = (MonoMethodMessage) request;
52 if (mMsg.MethodBase.IsConstructor)
53 return ActivateRemoteObject (mMsg);
55 if (mMsg.MethodBase == _cache_GetHashCodeMethod)
56 return new MethodResponse(ObjectIdentity.GetHashCode(), null, null, request as IMethodCallMessage);
\r
58 if (mMsg.MethodBase == _cache_GetTypeMethod)
59 return new MethodResponse(GetProxiedType(), null, null, request as IMethodCallMessage);
\r
61 mMsg.Uri = _objectIdentity.ObjectUri;
62 ((IInternalMessage)mMsg).TargetIdentity = _objectIdentity;
64 // Exiting from the context?
65 if (!Thread.CurrentContext.IsDefaultContext && !_hasEnvoySink)
66 return Thread.CurrentContext.GetClientContextSinkChain ().SyncProcessMessage (request);
68 return _sink.SyncProcessMessage (request);
71 IMessage ActivateRemoteObject (IMethodMessage request)
73 if (_activationUrl == null)
74 return new ReturnMessage (this, new object[0], 0, null, (IMethodCallMessage) request); // Ignore constructor call for WKOs
76 IMethodReturnMessage response;
78 _ctorCall.CopyFrom (request);
80 if (_activationUrl == ChannelServices.CrossContextUrl)
82 // Cross context activation
84 _objectIdentity = RemotingServices.CreateContextBoundObjectIdentity (_ctorCall.ActivationType);
85 RemotingServices.SetMessageTargetIdentity (_ctorCall, _objectIdentity);
86 response = _ctorCall.Activator.Activate (_ctorCall);
92 RemoteActivator remoteActivator = (RemoteActivator) RemotingServices.Connect (typeof (RemoteActivator), _activationUrl);
95 response = remoteActivator.Activate (_ctorCall) as IMethodReturnMessage;
97 catch (Exception ex) {
98 return new ReturnMessage (ex, (IMethodCallMessage)request);
101 ObjRef objRef = (ObjRef) response.ReturnValue;
102 if (RemotingServices.GetIdentityForUri (objRef.URI) != null)
103 throw new RemotingException("Inconsistent state during activation; there may be two proxies for the same object");
105 _objectIdentity = RemotingServices.GetOrCreateClientIdentity (objRef, this);
108 if (_objectIdentity.EnvoySink != null)
110 _sink = _objectIdentity.EnvoySink;
111 _hasEnvoySink = true;
114 _sink = _objectIdentity.ChannelSink;
116 _activationUrl = null;