2 // System.Runtime.Remoting.ActivationServices.cs
4 // Author: Lluis Sanchez Gual (lluis@ideary.com)
6 // (C) 2002, Lluis Sanchez Gual
10 using System.Threading;
11 using System.Runtime.Remoting.Messaging;
12 using System.Runtime.Remoting.Activation;
13 using System.Runtime.Remoting.Contexts;
14 using System.Runtime.Remoting.Proxies;
15 using System.Reflection;
16 using System.Runtime.CompilerServices;
17 using System.Collections;
18 using System.Runtime.Remoting.Channels;
20 namespace System.Runtime.Remoting.Activation
22 internal class ActivationServices
24 static IActivator _constructionActivator = new ConstructionLevelActivator ();
26 public static IMessage Activate (RemotingProxy proxy, ConstructionCall ctorCall)
30 if (Thread.CurrentContext.HasExitSinks && !ctorCall.IsContextOk)
31 response = Thread.CurrentContext.GetClientContextSinkChain ().SyncProcessMessage (ctorCall);
33 response = RemoteActivate (ctorCall);
35 if (response is IConstructionReturnMessage)
37 Identity identity = RemotingServices.GetMessageTargetIdentity (ctorCall);
38 proxy.AttachIdentity (identity);
44 public static IMessage RemoteActivate (IConstructionCallMessage ctorCall)
48 return ctorCall.Activator.Activate (ctorCall);
50 catch (Exception ex)
\r
52 return new ReturnMessage (ex, ctorCall);
56 public static object CreateProxyFromAttributes (Type type, object[] activationAttributes)
58 string activationUrl = null;
59 foreach (object attr in activationAttributes)
61 if (!(attr is IContextAttribute)) throw new RemotingException ("Activation attribute does not implement the IContextAttribute interface");
62 if (attr is UrlAttribute) activationUrl = ((UrlAttribute)attr).UrlValue;
65 if (activationUrl != null)
66 return RemotingServices.CreateClientProxy (type, activationUrl, activationAttributes);
68 ActivatedClientTypeEntry activatedEntry = RemotingConfiguration.IsRemotelyActivatedClientType (type);
69 if (activatedEntry != null)
70 return RemotingServices.CreateClientProxy (activatedEntry, activationAttributes);
72 if (type.IsContextful)
73 return RemotingServices.CreateClientProxyForContextBound (type, activationAttributes);
78 public static ConstructionCall CreateConstructionCall (Type type, string activationUrl, object[] activationAttributes)
80 ConstructionCall ctorCall = new ConstructionCall (type);
82 if (!type.IsContextful)
84 // Must be a remote activated object
85 ctorCall.Activator = new AppDomainLevelActivator (activationUrl, _constructionActivator);
86 ctorCall.IsContextOk = false; // It'll be activated in a remote context
90 // It is a CBO. Need collect context properties and
91 // check if a new context is needed.
93 IActivator activatorChain = _constructionActivator;
94 activatorChain = new ContextLevelActivator (activatorChain);
96 ArrayList attributes = new ArrayList ();
97 if (activationAttributes != null) attributes.AddRange (activationAttributes);
99 bool isContextOk = (activationUrl == ChannelServices.CrossContextUrl); // Remote CBOs are always created in a new context
100 Context currentContext = Threading.Thread.CurrentContext;
104 foreach (IContextAttribute attr in attributes)
106 if (!attr.IsContextOK (currentContext, ctorCall))
114 object[] typeAttributes = type.GetCustomAttributes (true);
115 foreach (object attr in typeAttributes)
117 if (attr is IContextAttribute)
119 isContextOk = isContextOk && ((IContextAttribute)attr).IsContextOK (currentContext, ctorCall);
120 attributes.Add (attr);
126 // A new context is needed. Collect the context properties and chain
127 // the context level activator.
129 ctorCall.SetActivationAttributes (attributes.ToArray());
131 foreach (IContextAttribute attr in attributes)
132 attr.GetPropertiesForNewContext (ctorCall);
135 if (activationUrl != ChannelServices.CrossContextUrl)
136 activatorChain = new AppDomainLevelActivator (activationUrl, activatorChain);
138 ctorCall.Activator = activatorChain;
139 ctorCall.IsContextOk = isContextOk;
144 public static IMessage CreateInstanceFromMessage (IConstructionCallMessage ctorCall)
146 object obj = AllocateUninitializedClassInstance (ctorCall.ActivationType);
147 ctorCall.MethodBase.Invoke (obj, ctorCall.Args);
149 ServerIdentity identity = (ServerIdentity) RemotingServices.GetMessageTargetIdentity (ctorCall);
151 identity.AttachServerObject ((MarshalByRefObject) obj, Threading.Thread.CurrentContext);
153 return new ConstructionResponse (obj, null, ctorCall);
156 public static object CreateProxyForType (Type type)
158 // Called by the runtime when creating an instance of a type
159 // that has been registered as remotely activated.
161 // First of all check for remote activation. If the object is not remote, then
162 // it may be contextbound.
164 ActivatedClientTypeEntry activatedEntry = RemotingConfiguration.IsRemotelyActivatedClientType (type);
165 if (activatedEntry != null)
166 return RemotingServices.CreateClientProxy (activatedEntry, null);
168 WellKnownClientTypeEntry wellknownEntry = RemotingConfiguration.IsWellKnownClientType (type);
169 if (wellknownEntry != null)
170 return RemotingServices.CreateClientProxy (wellknownEntry);
172 if (type.IsContextful)
173 return RemotingServices.CreateClientProxyForContextBound (type, null);
178 // Allocates an uninitialized instance. It never creates proxies.
179 [MethodImplAttribute(MethodImplOptions.InternalCall)]
180 public static extern object AllocateUninitializedClassInstance (Type type);
182 [MethodImplAttribute(MethodImplOptions.InternalCall)]
183 public extern static void EnableProxyActivation (Type type, bool enable);