Added testcase for generic registrations and a workaround for the CLR GetInterfaces...
[castle.git] / InversionOfControl / Castle.MicroKernel / Registration / ComponentRegistration.cs
blob5977b99661406dcb51bc33605a671d92616cab23
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.Registration
17 using System;
18 using System.Collections;
19 using System.Collections.Generic;
20 using Castle.Core;
21 using Castle.Core.Configuration;
22 using MicroKernel;
24 /// <summary>
25 ///
26 /// </summary>
27 /// <typeparam name="S">The service type</typeparam>
28 public class ComponentRegistration<S> : IRegistration
30 private String name;
31 private bool overwrite;
32 private Type serviceType;
33 private Type implementation;
34 private readonly List<ComponentDescriptor<S>> descriptors;
35 private ComponentModel componentModel;
37 /// <summary>
38 /// Initializes a new instance of the <see cref="ComponentRegistration{S}"/> class.
39 /// </summary>
40 public ComponentRegistration()
42 overwrite = false;
43 serviceType = typeof(S);
44 descriptors = new List<ComponentDescriptor<S>>();
47 public String Name
49 get { return name; }
52 public Type ServiceType
54 get { return serviceType; }
55 protected set { serviceType = value; }
58 public Type Implementation
60 get { return implementation; }
63 internal bool IsOverWrite
65 get { return overwrite; }
68 /// <summary>
69 /// With the overwrite.
70 /// </summary>
71 /// <returns></returns>
72 public ComponentRegistration<S> OverWrite()
74 overwrite = true;
75 return this;
78 /// <summary>
79 /// With the name.
80 /// </summary>
81 /// <param name="name">The name.</param>
82 /// <returns></returns>
83 public ComponentRegistration<S> Named(String name)
85 if (this.name != null)
87 String message = String.Format("This component has " +
88 "already been assigned name '{0}'", this.name);
90 throw new ComponentRegistrationException(message);
93 this.name = name;
94 return this;
97 public ComponentRegistration<S> ImplementedBy<C>()
99 return ImplementedBy(typeof(C));
102 public ComponentRegistration<S> ImplementedBy(Type type)
104 if (implementation != null)
106 String message = String.Format("This component has " +
107 "already been assigned implementation {0}", implementation.FullName);
108 throw new ComponentRegistrationException(message);
111 implementation = type;
112 return this;
115 /// <summary>
116 /// With the instance.
117 /// </summary>
118 /// <param name="instance">The instance.</param>
119 /// <returns></returns>
120 public ComponentRegistration<S> Instance(S instance)
122 return AddDescriptor(new ComponentInstanceDescriptior<S>(instance));
125 /// <summary>
126 /// Gets the proxy.
127 /// </summary>
128 /// <value>The proxy.</value>
129 public Proxy.ProxyGroup<S> Proxy
131 get { return new Proxy.ProxyGroup<S>(this); }
134 /// <summary>
135 /// Gets the with lifestyle.
136 /// </summary>
137 /// <value>The with lifestyle.</value>
138 public Lifestyle.LifestyleGroup<S> LifeStyle
140 get { return new Lifestyle.LifestyleGroup<S>(this); }
143 /// <summary>
144 /// With the activator.
145 /// </summary>
146 /// <returns></returns>
147 public ComponentRegistration<S> Activator<A>() where A : IComponentActivator
149 return AddAttributeDescriptor("componentActivatorType", typeof(A).AssemblyQualifiedName);
152 /// <summary>
153 /// With the extended properties.
154 /// </summary>
155 /// <param name="properties">The properties.</param>
156 /// <returns></returns>
157 public ComponentRegistration<S> ExtendedProperties(params Property[] properties)
159 return AddDescriptor(new ExtendedPropertiesDescriptor<S>(properties));
162 /// <summary>
163 /// With the extended properties.
164 /// </summary>
165 /// <param name="anonymous">The properties.</param>
166 /// <returns></returns>
167 public ComponentRegistration<S> ExtendedProperties(object anonymous)
169 return AddDescriptor(new ExtendedPropertiesDescriptor<S>(anonymous));
172 /// <summary>
173 /// With the custom dependencies.
174 /// </summary>
175 /// <param name="dependencies">The dependencies.</param>
176 /// <returns></returns>
177 public ComponentRegistration<S> CustomDependencies(params Property[] dependencies)
179 return AddDescriptor(new CustomDependencyDescriptor<S>(dependencies));
182 /// <summary>
183 /// With the custom dependencies.
184 /// </summary>
185 /// <param name="dependencies">The dependencies.</param>
186 /// <returns></returns>
187 public ComponentRegistration<S> CustomDependencies(IDictionary dependencies)
189 return AddDescriptor(new CustomDependencyDescriptor<S>(dependencies));
192 /// <summary>
193 /// With the custom dependencies.
194 /// </summary>
195 /// <param name="anonymous">The dependencies.</param>
196 /// <returns></returns>
197 public ComponentRegistration<S> CustomDependencies(object anonymous)
199 return AddDescriptor(new CustomDependencyDescriptor<S>(anonymous));
202 /// <summary>
203 /// With the service overrides.
204 /// </summary>
205 /// <param name="overrides">The overrides.</param>
206 /// <returns></returns>
207 public ComponentRegistration<S> ServiceOverrides(params ServiceOverride[] overrides)
209 return AddDescriptor(new ServiceOverrideDescriptor<S>(overrides));
212 /// <summary>
213 /// With the service overrides.
214 /// </summary>
215 /// <param name="overrides">The overrides.</param>
216 /// <returns></returns>
217 public ComponentRegistration<S> ServiceOverrides(IDictionary overrides)
219 return AddDescriptor(new ServiceOverrideDescriptor<S>(overrides));
222 /// <summary>
223 /// With the service overrides.
224 /// </summary>
225 /// <param name="anonymous">The overrides.</param>
226 /// <returns></returns>
227 public ComponentRegistration<S> ServiceOverrides(object anonymous)
229 return AddDescriptor(new ServiceOverrideDescriptor<S>(anonymous));
232 /// <summary>
233 /// With the configuration parameters.
234 /// </summary>
235 /// <param name="parameters">The parameters.</param>
236 /// <returns></returns>
237 public ComponentRegistration<S> Parameters(params Parameter[] parameters)
239 return AddDescriptor(new ParametersDescriptor<S>(parameters));
242 /// <summary>
243 /// With the interceptors.
244 /// </summary>
245 /// <param name="interceptors">The interceptors.</param>
246 /// <returns></returns>
247 public Interceptor.InterceptorGroup<S> Interceptors(
248 params InterceptorReference[] interceptors)
250 return new Interceptor.InterceptorGroup<S>(this, interceptors);
253 /// <summary>
254 /// Ases the startable.
255 /// </summary>
256 /// <returns></returns>
257 public ComponentRegistration<S> Startable()
259 return AddDescriptor(new ExtendedPropertiesDescriptor<S>(
260 Property.ForKey("startable").Eq(true)));
263 /// <summary>
264 /// Registers this component with the <see cref="IKernel"/>.
265 /// </summary>
266 /// <param name="kernel">The kernel.</param>
267 void IRegistration.Register(IKernel kernel)
269 if (componentModel == null)
271 InitializeDefaults();
272 componentModel = BuildComponentModel(kernel);
273 kernel.AddCustomComponent(componentModel);
277 /// <summary>
278 /// Builds the component model.
279 /// </summary>
280 /// <returns></returns>
281 private ComponentModel BuildComponentModel(IKernel kernel)
283 IConfiguration configuration = EnsureComponentConfiguration(kernel);
284 foreach(ComponentDescriptor<S> descriptor in descriptors)
286 descriptor.ApplyToConfiguration(kernel, configuration);
289 ComponentModel model = kernel.ComponentModelBuilder.BuildModel(
290 name, serviceType, implementation, null);
291 foreach(ComponentDescriptor<S> descriptor in descriptors)
293 descriptor.ApplyToModel(kernel, model);
296 return model;
299 /// <summary>
300 /// Adds the attribute descriptor.
301 /// </summary>
302 /// <param name="key">The key.</param>
303 /// <param name="value">The value.</param>
304 /// <returns></returns>
305 public ComponentRegistration<S> AddAttributeDescriptor(string key, string value)
307 AddDescriptor(new AttributeDescriptor<S>(key, value));
308 return this;
311 /// <summary>
312 /// Adds the descriptor.
313 /// </summary>
314 /// <param name="descriptor">The descriptor.</param>
315 /// <returns></returns>
316 public ComponentRegistration<S> AddDescriptor(ComponentDescriptor<S> descriptor)
318 descriptor.Registration = this;
319 descriptors.Add(descriptor);
320 return this;
323 internal void AddParameter(IKernel kernel, ComponentModel model, String key, String value)
325 IConfiguration parameters = EnsureParametersConfiguration(kernel);
326 MutableConfiguration parameter = new MutableConfiguration(key, value);
327 parameters.Children.Add(parameter);
328 model.Parameters.Add(key, value);
331 internal void AddParameter(IKernel kernel, ComponentModel model, String key, IConfiguration value)
333 IConfiguration parameters = EnsureParametersConfiguration(kernel);
334 MutableConfiguration parameter = new MutableConfiguration(key);
335 parameter.Children.Add(value);
336 parameters.Children.Add(parameter);
337 model.Parameters.Add(key, value);
340 private void InitializeDefaults()
342 if (implementation == null)
344 implementation = serviceType;
347 if (String.IsNullOrEmpty(name))
349 name = implementation.FullName;
353 private IConfiguration EnsureParametersConfiguration(IKernel kernel)
355 IConfiguration configuration = EnsureComponentConfiguration(kernel);
356 IConfiguration parameters = configuration.Children["parameters"];
357 if (parameters == null)
359 parameters = new MutableConfiguration("component");
360 configuration.Children.Add(parameters);
362 return parameters;
365 private IConfiguration EnsureComponentConfiguration(IKernel kernel)
367 IConfiguration configuration = kernel.ConfigurationStore.GetComponentConfiguration(name);
368 if (configuration == null)
370 configuration = new MutableConfiguration("component");
371 kernel.ConfigurationStore.AddComponentConfiguration(name, configuration);
373 return configuration;
377 public class ComponentRegistration : ComponentRegistration<object>
379 public ComponentRegistration()
383 public ComponentRegistration(Type serviceType)
385 ServiceType = serviceType;
388 public ComponentRegistration For(Type serviceType)
390 if (ServiceType != null)
392 String message = String.Format("This component has " +
393 "already been assigned service type {0}", ServiceType.FullName);
394 throw new ComponentRegistrationException(message);
397 ServiceType = serviceType;
398 return this;