2 // System.Runtime.Remoting.Identity.cs
4 // Author: Lluis Sanchez Gual (lluis@ideary.com)
6 // (C) 2002, Lluis Sanchez Gual
10 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
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.
33 using System
.Runtime
.Remoting
.Messaging
;
34 using System
.Runtime
.Remoting
.Contexts
;
35 using System
.Runtime
.Remoting
.Lifetime
;
36 using System
.Runtime
.Remoting
.Proxies
;
38 namespace System
.Runtime
.Remoting
40 internal abstract class ServerIdentity
: Identity
42 protected Type _objectType
;
44 protected MarshalByRefObject _serverObject
;
46 // Message sink used in the server to dispatch a message
47 // to the server object
48 protected IMessageSink _serverSink
= null;
50 protected Context _context
;
51 protected Lease _lease
;
53 public ServerIdentity (string objectUri
, Context context
, Type objectType
): base (objectUri
)
55 _objectType
= objectType
;
59 public Type ObjectType
61 get { return _objectType; }
64 public void StartTrackingLifetime (ILease lease
)
66 // Adds this identity to the LeaseManager.
67 // _serverObject must be set.
69 if (lease
!= null && lease
.CurrentState
== LeaseState
.Null
) lease
= null;
73 if (! (lease
is Lease
)) lease
= new Lease(); // This seems to be MS behavior
74 _lease
= (Lease
) lease
;
75 LifetimeServices
.TrackLifetime (this);
79 public virtual void OnLifetimeExpired()
81 DisposeServerObject();
84 public override ObjRef
CreateObjRef (Type requestedType
)
88 // Just update channel info. It may have changed.
89 _objRef
.UpdateChannelInfo();
93 if (requestedType
== null) requestedType
= _objectType
;
94 _objRef
= new ObjRef ();
95 _objRef
.TypeInfo
= new TypeInfo(requestedType
);
96 _objRef
.URI
= _objectUri
;
98 if (_envoySink
!= null && !(_envoySink
is EnvoyTerminatorSink
))
99 _objRef
.EnvoyInfo
= new EnvoyInfo (_envoySink
);
104 public void AttachServerObject (MarshalByRefObject serverObject
, Context context
)
107 _serverObject
= serverObject
;
109 if (RemotingServices
.IsTransparentProxy (serverObject
))
111 RealProxy rp
= RemotingServices
.GetRealProxy (serverObject
);
112 if (rp
.ObjectIdentity
== null)
113 rp
.ObjectIdentity
= this;
117 if (_objectType
.IsContextful
)
118 _envoySink
= context
.CreateEnvoySink (serverObject
);
120 _serverObject
.ObjectIdentity
= this;
126 get { return _lease; }
129 public Context Context
131 get { return _context; }
132 set { _context = value; }
135 public abstract IMessage
SyncObjectProcessMessage (IMessage msg
);
136 public abstract IMessageCtrl
AsyncObjectProcessMessage (IMessage msg
, IMessageSink replySink
);
138 protected void DisposeServerObject()
140 // Detach identity from server object to avoid problems if the
141 // object is marshalled again.
143 if (_serverObject
!= null) {
144 _serverObject
.ObjectIdentity
= null;
145 _serverObject
= null;
150 internal class ClientActivatedIdentity
: ServerIdentity
152 MarshalByRefObject _targetThis
;
154 public ClientActivatedIdentity (string objectUri
, Type objectType
): base (objectUri
, null, objectType
)
158 public MarshalByRefObject
GetServerObject ()
160 return _serverObject
;
163 public MarshalByRefObject
GetClientProxy ()
168 public void SetClientProxy (MarshalByRefObject obj
)
173 public override void OnLifetimeExpired()
175 base.OnLifetimeExpired();
176 RemotingServices
.DisposeIdentity (this);
179 public override IMessage
SyncObjectProcessMessage (IMessage msg
)
181 if (_serverSink
== null) {
182 bool useProxy
= _targetThis
!= null;
183 _serverSink
= _context
.CreateServerObjectSinkChain ((useProxy
? _targetThis
: _serverObject
), useProxy
);
185 return _serverSink
.SyncProcessMessage (msg
);
188 public override IMessageCtrl
AsyncObjectProcessMessage (IMessage msg
, IMessageSink replySink
)
190 if (_serverSink
== null) {
191 bool useProxy
= _targetThis
!= null;
192 _serverSink
= _context
.CreateServerObjectSinkChain ((useProxy
? _targetThis
: _serverObject
), useProxy
);
194 return _serverSink
.AsyncProcessMessage (msg
, replySink
);
198 internal class SingletonIdentity
: ServerIdentity
200 public SingletonIdentity (string objectUri
, Context context
, Type objectType
): base (objectUri
, context
, objectType
)
204 public MarshalByRefObject
GetServerObject ()
206 if (_serverObject
!= null) return _serverObject
;
210 if (_serverObject
== null) {
211 MarshalByRefObject server
= (MarshalByRefObject
) Activator
.CreateInstance (_objectType
, true);
212 AttachServerObject (server
, Context
.DefaultContext
);
213 StartTrackingLifetime ((ILease
)server
.InitializeLifetimeService ());
216 return _serverObject
;
219 public override IMessage
SyncObjectProcessMessage (IMessage msg
)
221 MarshalByRefObject obj
= GetServerObject ();
222 if (_serverSink
== null) _serverSink
= _context
.CreateServerObjectSinkChain (obj
, false);
223 return _serverSink
.SyncProcessMessage (msg
);
226 public override IMessageCtrl
AsyncObjectProcessMessage (IMessage msg
, IMessageSink replySink
)
228 MarshalByRefObject obj
= GetServerObject ();
229 if (_serverSink
== null) _serverSink
= _context
.CreateServerObjectSinkChain (obj
, false);
230 return _serverSink
.AsyncProcessMessage (msg
, replySink
);
234 internal class SingleCallIdentity
: ServerIdentity
236 public SingleCallIdentity (string objectUri
, Context context
, Type objectType
): base (objectUri
, context
, objectType
)
240 public override IMessage
SyncObjectProcessMessage (IMessage msg
)
242 // SingleCallIdentity creates and disposes an instance in each call
244 MarshalByRefObject obj
= (MarshalByRefObject
)Activator
.CreateInstance (_objectType
, true);
245 if (obj
.ObjectIdentity
== null) obj
.ObjectIdentity
= this;
246 IMessageSink serverSink
= _context
.CreateServerObjectSinkChain (obj
, false);
247 IMessage result
= serverSink
.SyncProcessMessage (msg
);
248 if (obj
is IDisposable
) ((IDisposable
)obj
).Dispose();
252 public override IMessageCtrl
AsyncObjectProcessMessage (IMessage msg
, IMessageSink replySink
)
254 MarshalByRefObject obj
= (MarshalByRefObject
)Activator
.CreateInstance (_objectType
, true);
255 IMessageSink serverSink
= _context
.CreateServerObjectSinkChain (obj
, false);
256 if (obj
is IDisposable
) replySink
= new DisposerReplySink(replySink
, ((IDisposable
)obj
));
257 return serverSink
.AsyncProcessMessage (msg
, replySink
);
261 internal class DisposerReplySink
: IMessageSink
264 IDisposable _disposable
;
266 public DisposerReplySink (IMessageSink next
, IDisposable disposable
)
269 _disposable
= disposable
;
272 public IMessage
SyncProcessMessage (IMessage msg
)
274 _disposable
.Dispose();
275 return _next
.SyncProcessMessage (msg
);
278 public IMessageCtrl
AsyncProcessMessage (IMessage msg
, IMessageSink replySink
)
280 throw new NotSupportedException();
283 public IMessageSink NextSink
285 get { return _next; }