Adding CreateInstance() method to WindsorContainer, allowing to use the container...
[castle.git] / InversionOfControl / Castle.MicroKernel / SubSystems / Naming / DefaultNamingSubSystem.cs
bloba8efc591bf1e8fee5269926fe6774bea9c040802
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.MicroKernel.SubSystems.Naming
17 using System;
18 using System.Collections;
19 using System.Collections.Specialized;
20 using System.Threading;
22 /// <summary>
23 /// Default <see cref="INamingSubSystem"/> implementation.
24 /// Keeps services map as a simple hash table.
25 /// Keeps key map as a list dictionary to maintain order.
26 /// Does not support a query string.
27 /// </summary>
28 [Serializable]
29 public class DefaultNamingSubSystem : AbstractSubSystem, INamingSubSystem
31 /// <summary>
32 /// Map(String, IHandler) to map component keys
33 /// to <see cref="IHandler"/>
34 /// Items in this dictionary are sorted in insertion order.
35 /// </summary>
36 protected IDictionary key2Handler;
38 /// <summary>
39 /// Map(Type, IHandler) to map a service
40 /// to <see cref="IHandler"/>.
41 /// If there is more than a single service of the type, only the first
42 /// registered services is stored in this dictionary.
43 /// It serve as a fast lookup for the common case of having a single handler for
44 /// a type.
45 /// </summary>
46 protected IDictionary service2Handler;
48 private readonly ReaderWriterLock locker = new ReaderWriterLock();
50 /// <summary>
51 /// Initializes a new instance of the <see cref="DefaultNamingSubSystem"/> class.
52 /// </summary>
53 public DefaultNamingSubSystem()
55 key2Handler = new OrderedDictionary();
56 service2Handler = new Hashtable();
59 #region INamingSubSystem Members
61 public virtual void Register(String key, IHandler handler)
63 Type service = handler.ComponentModel.Service;
65 try
67 locker.AcquireWriterLock(Timeout.Infinite);
68 if (key2Handler.Contains(key))
70 throw new ComponentRegistrationException(
71 String.Format("There is a component already registered for the given key {0}", key));
74 if (!service2Handler.Contains(service))
76 this[service] = handler;
79 this[key] = handler;
81 finally
83 locker.ReleaseLock();
87 public virtual bool Contains(String key)
89 try
91 locker.AcquireReaderLock(Timeout.Infinite);
92 return key2Handler.Contains(key);
94 finally
96 locker.ReleaseLock();
100 public virtual bool Contains(Type service)
104 locker.AcquireReaderLock(Timeout.Infinite);
105 return service2Handler.Contains(service);
107 finally
109 locker.ReleaseLock();
113 public virtual void UnRegister(String key)
117 locker.AcquireWriterLock(Timeout.Infinite);
118 key2Handler.Remove(key);
120 finally
122 locker.ReleaseLock();
126 public virtual void UnRegister(Type service)
130 locker.AcquireWriterLock(Timeout.Infinite);
131 service2Handler.Remove(service);
133 finally
135 locker.ReleaseLock();
139 public virtual int ComponentCount
145 locker.AcquireReaderLock(Timeout.Infinite);
146 return key2Handler.Count;
148 finally
150 locker.ReleaseLock();
155 public virtual IHandler GetHandler(String key)
157 if (key == null) throw new ArgumentNullException("key");
161 locker.AcquireReaderLock(Timeout.Infinite);
162 return key2Handler[key] as IHandler;
164 finally
166 locker.ReleaseLock();
170 public virtual IHandler[] GetHandlers(String query)
172 throw new NotImplementedException();
175 public virtual IHandler GetHandler(Type service)
177 if (service == null) throw new ArgumentNullException("service");
181 locker.AcquireReaderLock(Timeout.Infinite);
182 IHandler handler = service2Handler[service] as IHandler;
184 return handler;
186 finally
188 locker.ReleaseLock();
192 public virtual IHandler GetHandler(String key, Type service)
194 if (key == null) throw new ArgumentNullException("key");
195 if (service == null) throw new ArgumentNullException("service");
199 locker.AcquireReaderLock(Timeout.Infinite);
200 IHandler handler = key2Handler[key] as IHandler;
202 return handler;
204 finally
206 locker.ReleaseLock();
210 public virtual IHandler[] GetHandlers(Type service)
212 if (service == null) throw new ArgumentNullException("service");
214 ArrayList list = new ArrayList();
216 foreach (IHandler handler in GetHandlers())
218 if (service == handler.ComponentModel.Service)
220 list.Add(handler);
224 return (IHandler[]) list.ToArray(typeof (IHandler));
227 public virtual IHandler[] GetAssignableHandlers(Type service)
229 if (service == null) throw new ArgumentNullException("service");
231 ArrayList list = new ArrayList();
233 foreach (IHandler handler in GetHandlers())
235 Type handlerService = handler.ComponentModel.Service;
236 if (service.IsAssignableFrom(handlerService))
238 list.Add(handler);
240 else
242 if (service.IsGenericType &&
243 service.GetGenericTypeDefinition().IsAssignableFrom(handlerService))
245 list.Add(handler);
250 return (IHandler[]) list.ToArray(typeof (IHandler));
253 public virtual IHandler[] GetHandlers()
257 locker.AcquireReaderLock(Timeout.Infinite);
258 IHandler[] list = new IHandler[key2Handler.Values.Count];
260 int index = 0;
262 foreach (IHandler handler in key2Handler.Values)
264 list[index++] = handler;
267 return list;
269 finally
271 locker.ReleaseLock();
275 public virtual IHandler this[Type service]
281 locker.AcquireWriterLock(Timeout.Infinite);
282 service2Handler[service] = value;
284 finally
286 locker.ReleaseLock();
291 public virtual IHandler this[String key]
297 locker.AcquireWriterLock(Timeout.Infinite);
298 key2Handler[key] = value;
300 finally
302 locker.ReleaseLock();
307 public IDictionary GetKey2Handler()
309 return key2Handler;
312 public IDictionary GetService2Handler()
314 return service2Handler;
317 #endregion