//
// (C) 2002, Lluis Sanchez Gual
//
-\r
-using System;\r
-using System.Runtime.Remoting.Messaging;\r
-using System.Runtime.Remoting.Activation;\r
-using System.Runtime.Remoting.Contexts;\r
-using System.Reflection;\r
+
+using System;
+using System.Threading;
+using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Activation;
+using System.Runtime.Remoting.Contexts;
+using System.Runtime.Remoting.Proxies;
+using System.Reflection;
using System.Runtime.CompilerServices;
using System.Collections;
using System.Runtime.Remoting.Channels;
-\r
-namespace System.Runtime.Remoting.Activation\r
-{\r
- internal class ActivationServices\r
- {\r
- static IActivator _constructionActivator = new ConstructionLevelActivator ();\r
-\r
- public static object CreateProxyFromAttributes (Type type, object[] activationAttributes)\r
- {\r
- string activationUrl = null;\r
+
+namespace System.Runtime.Remoting.Activation
+{
+ internal class ActivationServices
+ {
+ static IActivator _constructionActivator = new ConstructionLevelActivator ();
+
+ public static IMessage Activate (RemotingProxy proxy, ConstructionCall ctorCall)
+ {
+ IMessage response;
+
+ if (Thread.CurrentContext.HasExitSinks && !ctorCall.IsContextOk)
+ response = Thread.CurrentContext.GetClientContextSinkChain ().SyncProcessMessage (ctorCall);
+ else
+ response = RemoteActivate (ctorCall);
+
+ if (response is IConstructionReturnMessage)
+ {
+ Identity identity = RemotingServices.GetMessageTargetIdentity (ctorCall);
+ proxy.AttachIdentity (identity);
+ }
+
+ return response;
+ }
+
+ public static IMessage RemoteActivate (IConstructionCallMessage ctorCall)
+ {
+ try \r
+ {
+ return ctorCall.Activator.Activate (ctorCall);
+ }
+ catch (Exception ex) \r
+ {
+ return new ReturnMessage (ex, ctorCall);
+ } \r
+ }
+
+ public static object CreateProxyFromAttributes (Type type, object[] activationAttributes)
+ {
+ string activationUrl = null;
foreach (object attr in activationAttributes)
{
if (!(attr is IContextAttribute)) throw new RemotingException ("Activation attribute does not implement the IContextAttribute interface");
if (attr is UrlAttribute) activationUrl = ((UrlAttribute)attr).UrlValue;
}
-\r
+
if (activationUrl != null)
return RemotingServices.CreateClientProxy (type, activationUrl, activationAttributes);
return RemotingServices.CreateClientProxyForContextBound (type, activationAttributes);
return null;
- }\r
-\r
+ }
+
public static ConstructionCall CreateConstructionCall (Type type, string activationUrl, object[] activationAttributes)
{
ConstructionCall ctorCall = new ConstructionCall (type);
- ctorCall.Activator = _constructionActivator;
- if (!type.IsContextful) return ctorCall;
+ if (!type.IsContextful)
+ {
+ // Must be a remote activated object
+ ctorCall.Activator = new AppDomainLevelActivator (activationUrl, _constructionActivator);
+ ctorCall.IsContextOk = false; // It'll be activated in a remote context
+ return ctorCall;
+ }
+
+ // It is a CBO. Need collect context properties and
+ // check if a new context is needed.
+
+ IActivator activatorChain = _constructionActivator;
+ activatorChain = new ContextLevelActivator (activatorChain);
ArrayList attributes = new ArrayList ();
if (activationAttributes != null) attributes.AddRange (activationAttributes);
bool isContextOk = (activationUrl == ChannelServices.CrossContextUrl); // Remote CBOs are always created in a new context
Context currentContext = Threading.Thread.CurrentContext;
- if (isContextOk) \r
+ if (isContextOk)
{
- foreach (IContextAttribute attr in attributes) \r
+ foreach (IContextAttribute attr in attributes)
{
- if (!attr.IsContextOK (currentContext, ctorCall)) \r
+ if (!attr.IsContextOK (currentContext, ctorCall))
{
isContextOk = false;
break;
}
object[] typeAttributes = type.GetCustomAttributes (true);
- foreach (object attr in typeAttributes) \r
+ foreach (object attr in typeAttributes)
{
- if (attr is IContextAttribute) \r
- {\r
- isContextOk = isContextOk && ((IContextAttribute)attr).IsContextOK (currentContext, ctorCall);\r
+ if (attr is IContextAttribute)
+ {
+ isContextOk = isContextOk && ((IContextAttribute)attr).IsContextOK (currentContext, ctorCall);
attributes.Add (attr);
}
}
if (!isContextOk)
{
- // A new context is needed. Collect the context properties and set
+ // A new context is needed. Collect the context properties and chain
// the context level activator.
ctorCall.SetActivationAttributes (attributes.ToArray());
- ctorCall.Activator = new ContextLevelActivator (ctorCall.Activator);
foreach (IContextAttribute attr in attributes)
attr.GetPropertiesForNewContext (ctorCall);
}
+ if (activationUrl != ChannelServices.CrossContextUrl)
+ activatorChain = new AppDomainLevelActivator (activationUrl, activatorChain);
+
+ ctorCall.Activator = activatorChain;
+ ctorCall.IsContextOk = isContextOk;
+
return ctorCall;
- }\r
-\r
- public static IMessage CreateInstanceFromMessage (IConstructionCallMessage ctorCall)\r
- {\r
- object obj = AllocateUninitializedClassInstance (ctorCall.ActivationType);\r
- ctorCall.MethodBase.Invoke (obj, ctorCall.Args);\r
-\r
+ }
+
+ public static IMessage CreateInstanceFromMessage (IConstructionCallMessage ctorCall)
+ {
+ object obj = AllocateUninitializedClassInstance (ctorCall.ActivationType);
+ ctorCall.MethodBase.Invoke (obj, ctorCall.Args);
+
ServerIdentity identity = (ServerIdentity) RemotingServices.GetMessageTargetIdentity (ctorCall);
identity.AttachServerObject ((MarshalByRefObject) obj, Threading.Thread.CurrentContext);
return new ConstructionResponse (obj, null, ctorCall);
- }\r
-\r
+ }
+
public static object CreateProxyForType (Type type)
{
// Called by the runtime when creating an instance of a type
return RemotingServices.CreateClientProxyForContextBound (type, null);
return null;
- }\r
-\r
- // Allocates an uninitialized instance. It never creates proxies.\r
+ }
+
+ // Allocates an uninitialized instance. It never creates proxies.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern object AllocateUninitializedClassInstance (Type type);
-\r
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static void EnableProxyActivation (Type type, bool enable);
- }\r
-}\r
+ }
+}
--- /dev/null
+//
+// System.Runtime.Remoting.Activation.AppDomainLevelActivator.cs
+//
+// Author: Lluis Sanchez Gual (lluis@ideary.com)
+//
+// (C) 2003, Lluis Sanchez Gual
+//
+
+using System;
+using System.Runtime.Remoting.Messaging;
+
+namespace System.Runtime.Remoting.Activation
+{
+ public class AppDomainLevelActivator: IActivator
+ {
+ string _activationUrl;
+ IActivator _next;
+
+ public AppDomainLevelActivator(string activationUrl, IActivator next)
+ {
+ _activationUrl = activationUrl;
+ _next = next;
+ }
+
+ public ActivatorLevel Level
+ {
+ get { return ActivatorLevel.AppDomain; }
+ }
+
+ public IActivator NextActivator
+ {
+ get { return _next; }
+ set { _next = value; }
+ }
+
+ public IConstructionReturnMessage Activate (IConstructionCallMessage ctorCall)
+ {
+ IConstructionReturnMessage response;
+
+ // Create the object by calling the remote activation service
+
+ RemoteActivator remoteActivator = (RemoteActivator) RemotingServices.Connect (typeof (RemoteActivator), _activationUrl);
+ ctorCall.Activator = ctorCall.Activator.NextActivator;
+
+ response = remoteActivator.Activate (ctorCall);
+
+ // Create the client identity for the remote object
+
+ ObjRef objRef = (ObjRef) response.ReturnValue;
+ if (RemotingServices.GetIdentityForUri (objRef.URI) != null)
+ throw new RemotingException("Inconsistent state during activation; there may be two proxies for the same object");
+
+ Identity identity = RemotingServices.GetOrCreateClientIdentity (objRef, ctorCall.ActivationType);
+ RemotingServices.SetMessageTargetIdentity (ctorCall, identity);
+ return response;
+ }
+ }
+}