Added RedirectUsingNamedRoute
[castle.git] / InversionOfControl / Castle.MicroKernel / SubSystems / Naming / KeySearchNamingSubSystem.cs
blobeeb65c12b15c74df6686784033fa97f49add7fef
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.Runtime.CompilerServices;
21 /// <summary>
22 /// When requesting a component by service, KeySearchNamingSubSystem first
23 /// determines if more than one component has been registered for that service.
24 /// If not, Default resolution occurs. If so, all of the registered keys for
25 /// that service are processed through the provided Predicate to determine which
26 /// key to use for service resolution. If no Predicate matches, the default
27 /// resolution occurs.
28 /// </summary>
29 [Serializable]
30 public class KeySearchNamingSubSystem : DefaultNamingSubSystem
32 protected readonly IDictionary service2Keys;
33 protected readonly Predicate<string> keyPredicate;
35 /// <summary>
36 /// Initializes a new instance of the <see cref="KeySearchNamingSubSystem"/> class.
37 /// </summary>
38 public KeySearchNamingSubSystem() : this(delegate { return true; })
42 /// <summary>
43 /// Initializes a new instance of the <see cref="KeySearchNamingSubSystem"/> class.
44 /// </summary>
45 /// <param name="keyPredicate">The key predicate.</param>
46 public KeySearchNamingSubSystem(Predicate<string> keyPredicate)
48 if (keyPredicate == null) throw new ArgumentNullException("keyPredicate");
50 service2Keys = Hashtable.Synchronized(new Hashtable());
51 this.keyPredicate = keyPredicate;
54 /// <summary>
55 /// Registers the given handler with the give key.
56 /// </summary>
57 /// <param name="key">The key.</param>
58 /// <param name="handler">The handler.</param>
59 [MethodImpl(MethodImplOptions.Synchronized)]
60 public override void Register(string key, IHandler handler)
62 base.Register(key, handler);
64 Type service = handler.ComponentModel.Service;
66 IList keys;
68 if (!service2Keys.Contains(service))
70 if (!service2Keys.Contains(service))
72 keys = ArrayList.Synchronized(new ArrayList());
73 keys.Add(key);
74 service2Keys[service] = keys;
77 else
79 keys = (IList) service2Keys[service];
81 if (!keys.Contains(key))
83 if (!keys.Contains(key))
85 keys.Add(key);
91 /// <summary>
92 /// Unregisters the handler associated with the given key
93 /// </summary>
94 /// <param name="key">The key.</param>
95 [MethodImpl(MethodImplOptions.Synchronized)]
96 public override void UnRegister(string key)
98 IHandler handler = key2Handler[key] as IHandler;
100 base.UnRegister(key);
102 if (handler != null)
104 IList keys = service2Keys[handler.ComponentModel.Service] as IList;
105 if (keys != null)
107 keys.Remove(key);
112 /// <summary>
113 /// Unregisters the handler associated with the given service
114 /// </summary>
115 /// <param name="service">The service.</param>
116 [MethodImpl(MethodImplOptions.Synchronized)]
117 public override void UnRegister(Type service)
119 base.UnRegister(service);
120 service2Keys.Remove(service);
123 /// <summary>
124 /// Executes the Predicate against all keys for the registered service to
125 /// determine which component to return.
126 /// </summary>
127 /// <param name="service">The service.</param>
128 /// <returns></returns>
129 [MethodImpl(MethodImplOptions.Synchronized)]
130 public override IHandler GetHandler(Type service)
132 IList keys = service2Keys[service] as IList;
134 if (keys == null) return null;
136 if (keys.Count == 1) return base.GetHandler(service);
138 for(int i = 0; i < keys.Count; i++)
140 string key = (string) keys[i];
141 if (keyPredicate(key))
143 return GetHandler(key);
147 return base.GetHandler(service);