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
;
37 using System
.Runtime
.Remoting
.Services
;
39 namespace System
.Runtime
.Remoting
41 internal abstract class ServerIdentity
: Identity
43 protected Type _objectType
;
45 protected MarshalByRefObject _serverObject
;
47 // Message sink used in the server to dispatch a message
48 // to the server object
49 protected IMessageSink _serverSink
= null;
51 protected Context _context
;
52 protected Lease _lease
;
54 public ServerIdentity (string objectUri
, Context context
, Type objectType
): base (objectUri
)
56 _objectType
= objectType
;
60 public Type ObjectType
62 get { return _objectType; }
65 public void StartTrackingLifetime (ILease lease
)
67 // Adds this identity to the LeaseManager.
68 // _serverObject must be set.
70 if (lease
!= null && lease
.CurrentState
== LeaseState
.Null
) lease
= null;
74 if (! (lease
is Lease
)) lease
= new Lease(); // This seems to be MS behavior
75 _lease
= (Lease
) lease
;
76 LifetimeServices
.TrackLifetime (this);
80 public virtual void OnLifetimeExpired()
82 DisposeServerObject();
85 public override ObjRef
CreateObjRef (Type requestedType
)
89 // Just update channel info. It may have changed.
90 _objRef
.UpdateChannelInfo();
94 if (requestedType
== null) requestedType
= _objectType
;
95 _objRef
= new ObjRef ();
96 _objRef
.TypeInfo
= new TypeInfo(requestedType
);
97 _objRef
.URI
= _objectUri
;
99 if (_envoySink
!= null && !(_envoySink
is EnvoyTerminatorSink
))
100 _objRef
.EnvoyInfo
= new EnvoyInfo (_envoySink
);
105 public void AttachServerObject (MarshalByRefObject serverObject
, Context context
)
107 DisposeServerObject();
110 _serverObject
= serverObject
;
112 if (RemotingServices
.IsTransparentProxy (serverObject
))
114 RealProxy rp
= RemotingServices
.GetRealProxy (serverObject
);
115 if (rp
.ObjectIdentity
== null)
116 rp
.ObjectIdentity
= this;
120 if (_objectType
.IsContextful
)
121 _envoySink
= context
.CreateEnvoySink (serverObject
);
123 _serverObject
.ObjectIdentity
= this;
129 get { return _lease; }
132 public Context Context
134 get { return _context; }
135 set { _context = value; }
138 public abstract IMessage
SyncObjectProcessMessage (IMessage msg
);
139 public abstract IMessageCtrl
AsyncObjectProcessMessage (IMessage msg
, IMessageSink replySink
);
141 protected void DisposeServerObject()
143 // Detach identity from server object to avoid problems if the
144 // object is marshalled again.
146 if (_serverObject
!= null) {
147 MarshalByRefObject obj
= _serverObject
;
148 _serverObject
.ObjectIdentity
= null;
149 _serverObject
= null;
151 TrackingServices
.NotifyDisconnectedObject (obj
);
156 internal class ClientActivatedIdentity
: ServerIdentity
158 MarshalByRefObject _targetThis
;
160 public ClientActivatedIdentity (string objectUri
, Type objectType
): base (objectUri
, null, objectType
)
164 public MarshalByRefObject
GetServerObject ()
166 return _serverObject
;
169 public MarshalByRefObject
GetClientProxy ()
174 public void SetClientProxy (MarshalByRefObject obj
)
179 public override void OnLifetimeExpired()
181 base.OnLifetimeExpired();
182 RemotingServices
.DisposeIdentity (this);
185 public override IMessage
SyncObjectProcessMessage (IMessage msg
)
187 if (_serverSink
== null) {
188 bool useProxy
= _targetThis
!= null;
189 _serverSink
= _context
.CreateServerObjectSinkChain ((useProxy
? _targetThis
: _serverObject
), useProxy
);
191 return _serverSink
.SyncProcessMessage (msg
);
194 public override IMessageCtrl
AsyncObjectProcessMessage (IMessage msg
, IMessageSink replySink
)
196 if (_serverSink
== null) {
197 bool useProxy
= _targetThis
!= null;
198 _serverSink
= _context
.CreateServerObjectSinkChain ((useProxy
? _targetThis
: _serverObject
), useProxy
);
200 return _serverSink
.AsyncProcessMessage (msg
, replySink
);
204 internal class SingletonIdentity
: ServerIdentity
206 public SingletonIdentity (string objectUri
, Context context
, Type objectType
): base (objectUri
, context
, objectType
)
210 public MarshalByRefObject
GetServerObject ()
212 if (_serverObject
!= null) return _serverObject
;
216 if (_serverObject
== null) {
217 MarshalByRefObject server
= (MarshalByRefObject
) Activator
.CreateInstance (_objectType
, true);
218 AttachServerObject (server
, Context
.DefaultContext
);
219 StartTrackingLifetime ((ILease
)server
.InitializeLifetimeService ());
222 return _serverObject
;
225 public override IMessage
SyncObjectProcessMessage (IMessage msg
)
227 MarshalByRefObject obj
= GetServerObject ();
228 if (_serverSink
== null) _serverSink
= _context
.CreateServerObjectSinkChain (obj
, false);
229 return _serverSink
.SyncProcessMessage (msg
);
232 public override IMessageCtrl
AsyncObjectProcessMessage (IMessage msg
, IMessageSink replySink
)
234 MarshalByRefObject obj
= GetServerObject ();
235 if (_serverSink
== null) _serverSink
= _context
.CreateServerObjectSinkChain (obj
, false);
236 return _serverSink
.AsyncProcessMessage (msg
, replySink
);
240 internal class SingleCallIdentity
: ServerIdentity
242 public SingleCallIdentity (string objectUri
, Context context
, Type objectType
): base (objectUri
, context
, objectType
)
246 public override IMessage
SyncObjectProcessMessage (IMessage msg
)
248 // SingleCallIdentity creates and disposes an instance in each call
250 MarshalByRefObject obj
= (MarshalByRefObject
)Activator
.CreateInstance (_objectType
, true);
251 if (obj
.ObjectIdentity
== null) obj
.ObjectIdentity
= this;
252 IMessageSink serverSink
= _context
.CreateServerObjectSinkChain (obj
, false);
253 IMessage result
= serverSink
.SyncProcessMessage (msg
);
254 if (obj
is IDisposable
) ((IDisposable
)obj
).Dispose();
258 public override IMessageCtrl
AsyncObjectProcessMessage (IMessage msg
, IMessageSink replySink
)
260 MarshalByRefObject obj
= (MarshalByRefObject
)Activator
.CreateInstance (_objectType
, true);
261 IMessageSink serverSink
= _context
.CreateServerObjectSinkChain (obj
, false);
262 if (obj
is IDisposable
) replySink
= new DisposerReplySink(replySink
, ((IDisposable
)obj
));
263 return serverSink
.AsyncProcessMessage (msg
, replySink
);
267 internal class DisposerReplySink
: IMessageSink
270 IDisposable _disposable
;
272 public DisposerReplySink (IMessageSink next
, IDisposable disposable
)
275 _disposable
= disposable
;
278 public IMessage
SyncProcessMessage (IMessage msg
)
280 _disposable
.Dispose();
281 return _next
.SyncProcessMessage (msg
);
284 public IMessageCtrl
AsyncProcessMessage (IMessage msg
, IMessageSink replySink
)
286 throw new NotSupportedException();
289 public IMessageSink NextSink
291 get { return _next; }