//
// (C) 2002, Lluis Sanchez Gual
//
-\r
-using System;\r
-using System.Runtime.Remoting.Messaging;\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;
-\r
-namespace System.Runtime.Remoting.Activation\r
-{\r
- internal class ActivationServices\r
- {\r
- public static IMessage CreateInstanceFromMessage (IConstructionCallMessage ctorCall)\r
- {\r
- object obj = AllocateUninitializedClassInstance (ctorCall.ActivationType);\r
- ctorCall.MethodBase.Invoke (obj, ctorCall.Args);\r
-\r
+using System.Collections;
+using System.Runtime.Remoting.Channels;
+
+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 && ((IConstructionReturnMessage)response).Exception == null)
+ {
+ 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;
+ }
+
+ if (activationUrl != null)
+ return RemotingServices.CreateClientProxy (type, activationUrl, activationAttributes);
+
+ ActivatedClientTypeEntry activatedEntry = RemotingConfiguration.IsRemotelyActivatedClientType (type);
+ if (activatedEntry != null)
+ return RemotingServices.CreateClientProxy (activatedEntry, activationAttributes);
+
+ if (type.IsContextful)
+ return RemotingServices.CreateClientProxyForContextBound (type, activationAttributes);
+
+ return null;
+ }
+
+ public static ConstructionCall CreateConstructionCall (Type type, string activationUrl, object[] activationAttributes)
+ {
+ ConstructionCall ctorCall = new ConstructionCall (type);
+
+ 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)
+ {
+ foreach (IContextAttribute attr in attributes)
+ {
+ if (!attr.IsContextOK (currentContext, ctorCall))
+ {
+ isContextOk = false;
+ break;
+ }
+ }
+ }
+
+ object[] typeAttributes = type.GetCustomAttributes (true);
+ foreach (object attr in typeAttributes)
+ {
+ 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 chain
+ // the context level activator.
+
+ ctorCall.SetActivationAttributes (attributes.ToArray());
+
+ 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;
+ }
+
+ public static IMessage CreateInstanceFromMessage (IConstructionCallMessage ctorCall)
+ {
+ object obj = AllocateUninitializedClassInstance (ctorCall.ActivationType);
+ ctorCall.MethodBase.Invoke (obj, ctorCall.Args);
+
ServerIdentity identity = (ServerIdentity) RemotingServices.GetMessageTargetIdentity (ctorCall);
-// FIXME: restore when Thread.CurrentContext workds
-// identity.AttachServerObject ((MarshalByRefObject) obj, Threading.Thread.CurrentContext);
- identity.AttachServerObject ((MarshalByRefObject) obj, System.Runtime.Remoting.Contexts.Context.DefaultContext);
+ identity.AttachServerObject ((MarshalByRefObject) obj, Threading.Thread.CurrentContext);
return new ConstructionResponse (obj, null, ctorCall);
- }\r
-\r
- internal static object CreateProxyForType (Type type)
+ }
+
+ public static object CreateProxyForType (Type type)
{
// Called by the runtime when creating an instance of a type
// that has been registered as remotely activated.
ActivatedClientTypeEntry activatedEntry = RemotingConfiguration.IsRemotelyActivatedClientType (type);
if (activatedEntry != null)
- return RemotingServices.CreateClientProxy (activatedEntry);
+ return RemotingServices.CreateClientProxy (activatedEntry, null);
WellKnownClientTypeEntry wellknownEntry = RemotingConfiguration.IsWellKnownClientType (type);
if (wellknownEntry != null)
return RemotingServices.CreateClientProxy (wellknownEntry);
if (type.IsContextful)
- return RemotingServices.CreateClientProxyForContextBound (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
+ public static extern object AllocateUninitializedClassInstance (Type type);
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static void EnableProxyActivation (Type type, bool enable);
- }\r
-}\r
+ }
+}