1 // 2 // System.Runtime.Remoting.ActivationServices.cs 3 // 4 // Author: Lluis Sanchez Gual (lluis@ideary.com) 5 // 6 // (C) 2002, Lluis Sanchez Gual 7 // 8 9 // 10 // Copyright (C) 2004 Novell, Inc (http://www.novell.com) 11 // 12 // Permission is hereby granted, free of charge, to any person obtaining 13 // a copy of this software and associated documentation files (the 14 // "Software"), to deal in the Software without restriction, including 15 // without limitation the rights to use, copy, modify, merge, publish, 16 // distribute, sublicense, and/or sell copies of the Software, and to 17 // permit persons to whom the Software is furnished to do so, subject to 18 // the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be 21 // included in all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 // 31 32 using System; 33 using System.Threading; 34 using System.Runtime.Remoting.Messaging; 35 using System.Runtime.Remoting.Activation; 36 using System.Runtime.Remoting.Contexts; 37 using System.Runtime.Remoting.Proxies; 38 using System.Reflection; 39 using System.Runtime.CompilerServices; 40 using System.Collections; 41 using System.Runtime.Remoting.Channels; 42 43 namespace System.Runtime.Remoting.Activation 44 { 45 internal class ActivationServices 46 { 47 static IActivator _constructionActivator; 48 49 static IActivator ConstructionActivator { 50 get { 51 if (_constructionActivator == null) 52 _constructionActivator = new ConstructionLevelActivator (); 53 54 return _constructionActivator; 55 } 56 } 57 Activate(RemotingProxy proxy, ConstructionCall ctorCall)58 public static IMessage Activate (RemotingProxy proxy, ConstructionCall ctorCall) 59 { 60 IMessage response; 61 ctorCall.SourceProxy = proxy; 62 63 if (Thread.CurrentContext.HasExitSinks && !ctorCall.IsContextOk) 64 response = Thread.CurrentContext.GetClientContextSinkChain ().SyncProcessMessage (ctorCall); 65 else 66 response = RemoteActivate (ctorCall); 67 68 if (response is IConstructionReturnMessage && ((IConstructionReturnMessage)response).Exception == null && proxy.ObjectIdentity == null) 69 { 70 Identity identity = RemotingServices.GetMessageTargetIdentity (ctorCall); 71 proxy.AttachIdentity (identity); 72 } 73 74 return response; 75 } 76 RemoteActivate(IConstructionCallMessage ctorCall)77 public static IMessage RemoteActivate (IConstructionCallMessage ctorCall) 78 { 79 try 80 { 81 return ctorCall.Activator.Activate (ctorCall); 82 } 83 catch (Exception ex) 84 { 85 return new ReturnMessage (ex, ctorCall); 86 } 87 } 88 CreateProxyFromAttributes(Type type, object[] activationAttributes)89 public static object CreateProxyFromAttributes (Type type, object[] activationAttributes) 90 { 91 string activationUrl = null; 92 foreach (object attr in activationAttributes) 93 { 94 if (!(attr is IContextAttribute)) throw new RemotingException ("Activation attribute does not implement the IContextAttribute interface"); 95 if (attr is UrlAttribute) activationUrl = ((UrlAttribute)attr).UrlValue; 96 } 97 98 if (activationUrl != null) 99 return RemotingServices.CreateClientProxy (type, activationUrl, activationAttributes); 100 101 ActivatedClientTypeEntry activatedEntry = RemotingConfiguration.IsRemotelyActivatedClientType (type); 102 if (activatedEntry != null) 103 return RemotingServices.CreateClientProxy (activatedEntry, activationAttributes); 104 105 if (type.IsContextful) 106 return RemotingServices.CreateClientProxyForContextBound (type, activationAttributes); 107 108 return null; 109 } 110 CreateConstructionCall(Type type, string activationUrl, object[] activationAttributes)111 public static ConstructionCall CreateConstructionCall (Type type, string activationUrl, object[] activationAttributes) 112 { 113 ConstructionCall ctorCall = new ConstructionCall (type); 114 115 if (!type.IsContextful) 116 { 117 // Must be a remote activated object 118 ctorCall.Activator = new AppDomainLevelActivator (activationUrl, ConstructionActivator); 119 ctorCall.IsContextOk = false; // It'll be activated in a remote context 120 return ctorCall; 121 } 122 123 // It is a CBO. Need collect context properties and 124 // check if a new context is needed. 125 126 IActivator activatorChain = ConstructionActivator; 127 activatorChain = new ContextLevelActivator (activatorChain); 128 129 ArrayList attributes = new ArrayList (); 130 if (activationAttributes != null) attributes.AddRange (activationAttributes); 131 132 bool isContextOk = (activationUrl == ChannelServices.CrossContextUrl); // Remote CBOs are always created in a new context 133 Context currentContext = Threading.Thread.CurrentContext; 134 135 if (isContextOk) 136 { 137 foreach (IContextAttribute attr in attributes) 138 { 139 if (!attr.IsContextOK (currentContext, ctorCall)) 140 { 141 isContextOk = false; 142 break; 143 } 144 } 145 } 146 147 object[] typeAttributes = type.GetCustomAttributes (true); 148 foreach (object attr in typeAttributes) 149 { 150 if (attr is IContextAttribute) 151 { 152 isContextOk = isContextOk && ((IContextAttribute)attr).IsContextOK (currentContext, ctorCall); 153 attributes.Add (attr); 154 } 155 } 156 157 if (!isContextOk) 158 { 159 // A new context is needed. Collect the context properties and chain 160 // the context level activator. 161 162 ctorCall.SetActivationAttributes (attributes.ToArray()); 163 164 foreach (IContextAttribute attr in attributes) 165 attr.GetPropertiesForNewContext (ctorCall); 166 } 167 168 if (activationUrl != ChannelServices.CrossContextUrl) 169 activatorChain = new AppDomainLevelActivator (activationUrl, activatorChain); 170 171 ctorCall.Activator = activatorChain; 172 ctorCall.IsContextOk = isContextOk; 173 174 return ctorCall; 175 } 176 CreateInstanceFromMessage(IConstructionCallMessage ctorCall)177 public static IMessage CreateInstanceFromMessage (IConstructionCallMessage ctorCall) 178 { 179 object obj = AllocateUninitializedClassInstance (ctorCall.ActivationType); 180 181 ServerIdentity identity = (ServerIdentity) RemotingServices.GetMessageTargetIdentity (ctorCall); 182 identity.AttachServerObject ((MarshalByRefObject) obj, Threading.Thread.CurrentContext); 183 184 ConstructionCall call = ctorCall as ConstructionCall; 185 186 if (ctorCall.ActivationType.IsContextful && call != null && call.SourceProxy != null) 187 { 188 call.SourceProxy.AttachIdentity (identity); 189 MarshalByRefObject target = (MarshalByRefObject) call.SourceProxy.GetTransparentProxy (); 190 RemotingServices.InternalExecuteMessage (target, ctorCall); 191 } 192 else 193 ctorCall.MethodBase.Invoke (obj, ctorCall.Args); 194 195 return new ConstructionResponse (obj, null, ctorCall); 196 } 197 CreateProxyForType(Type type)198 public static object CreateProxyForType (Type type) 199 { 200 // Called by the runtime when creating an instance of a type 201 // that has been registered as remotely activated. 202 203 // First of all check for remote activation. If the object is not remote, then 204 // it may be contextbound. 205 206 ActivatedClientTypeEntry activatedEntry = RemotingConfiguration.IsRemotelyActivatedClientType (type); 207 if (activatedEntry != null) 208 return RemotingServices.CreateClientProxy (activatedEntry, null); 209 210 WellKnownClientTypeEntry wellknownEntry = RemotingConfiguration.IsWellKnownClientType (type); 211 if (wellknownEntry != null) 212 return RemotingServices.CreateClientProxy (wellknownEntry); 213 214 if (type.IsContextful) 215 return RemotingServices.CreateClientProxyForContextBound (type, null); 216 #if !MOBILE 217 if (type.IsCOMObject) { 218 return RemotingServices.CreateClientProxyForComInterop (type); 219 } 220 #endif 221 return null; 222 } 223 PushActivationAttributes(Type serverType, Object[] attributes)224 internal static void PushActivationAttributes (Type serverType, Object[] attributes) 225 { 226 // TODO: 227 } 228 PopActivationAttributes(Type serverType)229 internal static void PopActivationAttributes (Type serverType) 230 { 231 // TODO: 232 } 233 234 // Allocates an uninitialized instance. It never creates proxies. 235 [MethodImplAttribute(MethodImplOptions.InternalCall)] AllocateUninitializedClassInstance(Type type)236 public static extern object AllocateUninitializedClassInstance (Type type); 237 238 [MethodImplAttribute(MethodImplOptions.InternalCall)] EnableProxyActivation(Type type, bool enable)239 public extern static void EnableProxyActivation (Type type, bool enable); 240 } 241 } 242