1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.ActiveRecord
.Framework
.Scopes
18 using System
.Collections
.Generic
;
19 using Castle
.ActiveRecord
;
24 /// Abstract <seealso cref="ISessionScope"/> implementation
26 public abstract class AbstractScope
: MarshalByRefObject
, ISessionScope
28 private readonly SessionScopeType type
;
30 private readonly FlushAction flushAction
;
33 /// Map between a key to its session
35 protected IDictionary
<object, ISession
> key2Session
= new Dictionary
<object, ISession
>();
38 /// Initializes a new instance of the <see cref="AbstractScope"/> class.
40 /// <param name="flushAction">The flush action.</param>
41 /// <param name="type">The type.</param>
42 public AbstractScope(FlushAction flushAction
, SessionScopeType type
)
44 this.flushAction
= flushAction
;
47 ThreadScopeAccessor
.Instance
.RegisterScope(this);
51 /// Returns the <see cref="SessionScopeType"/> defined
54 public SessionScopeType ScopeType
60 /// Returns the <see cref="ISessionScope.FlushAction"/> defined
63 public FlushAction FlushAction
65 get { return flushAction; }
69 /// Flushes the sessions that this scope
72 public virtual void Flush()
74 foreach(ISession session
in GetSessions())
81 /// Evicts the specified instance from the session cache.
83 /// <param name="instance">The instance.</param>
84 public void Evict(object instance
)
86 if (instance
== null) throw new ArgumentNullException("instance");
88 foreach(ISession session
in GetSessions())
90 if (session
.Contains(instance
))
92 session
.Evict(instance
);
98 /// This method is invoked when the
99 /// <see cref="Castle.ActiveRecord.Framework.ISessionFactoryHolder"/>
100 /// instance needs a session instance. Instead of creating one it interrogates
101 /// the active scope for one. The scope implementation must check if it
102 /// has a session registered for the given key.
103 /// <seealso cref="RegisterSession"/>
105 /// <param name="key">an object instance</param>
107 /// <c>true</c> if the key exists within this scope instance
109 public virtual bool IsKeyKnown(object key
)
111 return key2Session
.ContainsKey(key
);
115 /// This method is invoked when no session was available
116 /// at and the <see cref="Castle.ActiveRecord.Framework.ISessionFactoryHolder"/>
117 /// just created one. So it registers the session created
118 /// within this scope using a key. The scope implementation
119 /// shouldn't make any assumption on what the key
120 /// actually is as we reserve the right to change it
121 /// <seealso cref="IsKeyKnown"/>
123 /// <param name="key">an object instance</param>
124 /// <param name="session">An instance of <c>ISession</c></param>
125 public virtual void RegisterSession(object key
, ISession session
)
127 key2Session
.Add(key
, session
);
133 /// This method should return the session instance associated with the key.
135 /// <param name="key">an object instance</param>
137 /// the session instance or null if none was found
139 public virtual ISession
GetSession(object key
)
141 return key2Session
[key
];
145 /// Implementors should return true if they
146 /// want that their scope implementation
147 /// be in charge of creating the session
150 public virtual bool WantsToCreateTheSession
156 /// If the <see cref="WantsToCreateTheSession"/> returned
157 /// <c>true</c> then this method is invoked to allow
158 /// the scope to create a properly configured session
160 /// <param name="sessionFactory">From where to open the session</param>
161 /// <param name="interceptor">the NHibernate interceptor</param>
162 /// <returns>the newly created session</returns>
163 public virtual ISession
OpenSession(ISessionFactory sessionFactory
, IInterceptor interceptor
)
165 ISession session
= sessionFactory
.OpenSession(interceptor
);
167 SetFlushMode(session
);
173 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
175 public void Dispose()
177 ThreadScopeAccessor
.Instance
.UnRegisterScope(this);
179 PerformDisposal(key2Session
.Values
);
183 /// Initializes the specified session.
185 /// <param name="session">The session.</param>
186 protected virtual void Initialize(ISession session
)
191 /// Performs the disposal.
193 /// <param name="sessions">The sessions.</param>
194 protected virtual void PerformDisposal(ICollection
<ISession
> sessions
)
199 /// Performs the disposal.
201 /// <param name="sessions">The sessions.</param>
202 /// <param name="flush">if set to <c>true</c> [flush].</param>
203 /// <param name="close">if set to <c>true</c> [close].</param>
204 protected internal void PerformDisposal(ICollection
<ISession
> sessions
, bool flush
, bool close
)
206 foreach(ISession session
in sessions
)
208 if (flush
) session
.Flush();
209 if (close
) session
.Close();
214 /// Discards the sessions.
216 /// <param name="sessions">The sessions.</param>
217 protected internal virtual void DiscardSessions(ICollection
<ISession
> sessions
)
219 foreach(ISession session
in sessions
)
221 RemoveSession(session
);
226 /// Marks the session as failed
228 /// <param name="session">The session</param>
229 public abstract void FailSession(ISession session
);
232 /// Sets the flush mode.
234 /// <param name="session">The session.</param>
235 protected void SetFlushMode(ISession session
)
237 if (FlushAction
== FlushAction
.Auto
)
239 session
.FlushMode
= FlushMode
.Auto
;
241 else if (FlushAction
== FlushAction
.Never
)
243 session
.FlushMode
= FlushMode
.Never
;
248 /// Gets the sessions.
250 /// <returns></returns>
251 internal ICollection
<ISession
> GetSessions()
253 return key2Session
.Values
;
257 /// Removes the session.
259 /// <param name="session">The session.</param>
260 private void RemoveSession(ISession session
)
262 foreach(KeyValuePair
<object, ISession
> entry
in key2Session
)
264 if (ReferenceEquals(entry
.Value
, session
))
267 key2Session
.Remove(entry
.Key
);