Removed untyped contructor from ComponentRegistration and add a protected setter.
[castle.git] / ActiveRecord / Castle.ActiveRecord / Framework / Scopes / AbstractScope.cs
blobee8e3ed90cb2e2c67224b92154616f1699ffd5aa
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
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
17 using System;
18 using System.Collections.Generic;
19 using Castle.ActiveRecord;
21 using NHibernate;
23 /// <summary>
24 /// Abstract <seealso cref="ISessionScope"/> implementation
25 /// </summary>
26 public abstract class AbstractScope : MarshalByRefObject, ISessionScope
28 private readonly SessionScopeType type;
30 private readonly FlushAction flushAction;
32 /// <summary>
33 /// Map between a key to its session
34 /// </summary>
35 protected IDictionary<object, ISession> key2Session = new Dictionary<object, ISession>();
37 /// <summary>
38 /// Initializes a new instance of the <see cref="AbstractScope"/> class.
39 /// </summary>
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;
45 this.type = type;
47 ThreadScopeAccessor.Instance.RegisterScope(this);
50 /// <summary>
51 /// Returns the <see cref="SessionScopeType"/> defined
52 /// for this scope
53 /// </summary>
54 public SessionScopeType ScopeType
56 get { return type; }
59 /// <summary>
60 /// Returns the <see cref="ISessionScope.FlushAction"/> defined
61 /// for this scope
62 /// </summary>
63 public FlushAction FlushAction
65 get { return flushAction; }
68 /// <summary>
69 /// Flushes the sessions that this scope
70 /// is maintaining
71 /// </summary>
72 public virtual void Flush()
74 foreach(ISession session in GetSessions())
76 session.Flush();
80 /// <summary>
81 /// Evicts the specified instance from the session cache.
82 /// </summary>
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);
97 /// <summary>
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"/>
104 /// </summary>
105 /// <param name="key">an object instance</param>
106 /// <returns>
107 /// <c>true</c> if the key exists within this scope instance
108 /// </returns>
109 public virtual bool IsKeyKnown(object key)
111 return key2Session.ContainsKey(key);
114 /// <summary>
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"/>
122 /// </summary>
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);
129 Initialize(session);
132 /// <summary>
133 /// This method should return the session instance associated with the key.
134 /// </summary>
135 /// <param name="key">an object instance</param>
136 /// <returns>
137 /// the session instance or null if none was found
138 /// </returns>
139 public virtual ISession GetSession(object key)
141 return key2Session[key];
144 /// <summary>
145 /// Implementors should return true if they
146 /// want that their scope implementation
147 /// be in charge of creating the session
148 /// </summary>
149 /// <value></value>
150 public virtual bool WantsToCreateTheSession
152 get { return true; }
155 /// <summary>
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
159 /// </summary>
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);
169 return session;
172 /// <summary>
173 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
174 /// </summary>
175 public void Dispose()
177 ThreadScopeAccessor.Instance.UnRegisterScope(this);
179 PerformDisposal(key2Session.Values);
182 /// <summary>
183 /// Initializes the specified session.
184 /// </summary>
185 /// <param name="session">The session.</param>
186 protected virtual void Initialize(ISession session)
190 /// <summary>
191 /// Performs the disposal.
192 /// </summary>
193 /// <param name="sessions">The sessions.</param>
194 protected virtual void PerformDisposal(ICollection<ISession> sessions)
198 /// <summary>
199 /// Performs the disposal.
200 /// </summary>
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();
213 /// <summary>
214 /// Discards the sessions.
215 /// </summary>
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);
225 /// <summary>
226 /// Marks the session as failed
227 /// </summary>
228 /// <param name="session">The session</param>
229 public abstract void FailSession(ISession session);
231 /// <summary>
232 /// Sets the flush mode.
233 /// </summary>
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;
247 /// <summary>
248 /// Gets the sessions.
249 /// </summary>
250 /// <returns></returns>
251 internal ICollection<ISession> GetSessions()
253 return key2Session.Values;
256 /// <summary>
257 /// Removes the session.
258 /// </summary>
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))
266 session.Close();
267 key2Session.Remove(entry.Key);
268 break;