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
.Runtime
.CompilerServices
;
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.
30 public class KeySearchNamingSubSystem
: DefaultNamingSubSystem
32 protected readonly IDictionary service2Keys
;
33 protected readonly Predicate
<string> keyPredicate
;
36 /// Initializes a new instance of the <see cref="KeySearchNamingSubSystem"/> class.
38 public KeySearchNamingSubSystem() : this(delegate { return true; }
)
43 /// Initializes a new instance of the <see cref="KeySearchNamingSubSystem"/> class.
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
;
55 /// Registers the given handler with the give key.
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
;
68 if (!service2Keys
.Contains(service
))
70 if (!service2Keys
.Contains(service
))
72 keys
= ArrayList
.Synchronized(new ArrayList());
74 service2Keys
[service
] = keys
;
79 keys
= (IList
) service2Keys
[service
];
81 if (!keys
.Contains(key
))
83 if (!keys
.Contains(key
))
92 /// Unregisters the handler associated with the given key
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
);
104 IList keys
= service2Keys
[handler
.ComponentModel
.Service
] as IList
;
113 /// Unregisters the handler associated with the given service
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
);
124 /// Executes the Predicate against all keys for the registered service to
125 /// determine which component to return.
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
);