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
.MicroKernel
.SubSystems
.Naming
18 using System
.Collections
;
19 using System
.Collections
.Specialized
;
20 using System
.Threading
;
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.
29 public class DefaultNamingSubSystem
: AbstractSubSystem
, INamingSubSystem
32 /// Map(String, IHandler) to map component keys
33 /// to <see cref="IHandler"/>
34 /// Items in this dictionary are sorted in insertion order.
36 protected IDictionary key2Handler
;
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
46 protected IDictionary service2Handler
;
48 private readonly ReaderWriterLock locker
= new ReaderWriterLock();
51 /// Initializes a new instance of the <see cref="DefaultNamingSubSystem"/> class.
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
;
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
;
87 public virtual bool Contains(String key
)
91 locker
.AcquireReaderLock(Timeout
.Infinite
);
92 return key2Handler
.Contains(key
);
100 public virtual bool Contains(Type service
)
104 locker
.AcquireReaderLock(Timeout
.Infinite
);
105 return service2Handler
.Contains(service
);
109 locker
.ReleaseLock();
113 public virtual void UnRegister(String key
)
117 locker
.AcquireWriterLock(Timeout
.Infinite
);
118 key2Handler
.Remove(key
);
122 locker
.ReleaseLock();
126 public virtual void UnRegister(Type service
)
130 locker
.AcquireWriterLock(Timeout
.Infinite
);
131 service2Handler
.Remove(service
);
135 locker
.ReleaseLock();
139 public virtual int ComponentCount
145 locker
.AcquireReaderLock(Timeout
.Infinite
);
146 return key2Handler
.Count
;
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
;
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
;
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
;
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
)
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
))
242 if (service
.IsGenericType
&&
243 service
.GetGenericTypeDefinition().IsAssignableFrom(handlerService
))
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
];
262 foreach (IHandler handler
in key2Handler
.Values
)
264 list
[index
++] = handler
;
271 locker
.ReleaseLock();
275 public virtual IHandler
this[Type service
]
281 locker
.AcquireWriterLock(Timeout
.Infinite
);
282 service2Handler
[service
] = value;
286 locker
.ReleaseLock();
291 public virtual IHandler
this[String key
]
297 locker
.AcquireWriterLock(Timeout
.Infinite
);
298 key2Handler
[key
] = value;
302 locker
.ReleaseLock();
307 public IDictionary
GetKey2Handler()
312 public IDictionary
GetService2Handler()
314 return service2Handler
;