Update registration fluent interface to support lists of service overrides (both...
[castle.git] / InversionOfControl / Castle.MicroKernel / Registration / ComponentRegiatration.cs
blob94556213b458297dcd3bba99c888ea56b158486a
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> : IComponentRegistration
30 private String name;
31 private bool overwrite;
32 private readonly Type serviceType;
33 private Type classType;
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()
41 : this(typeof(S))
45 protected ComponentRegistration(Type serviceType)
47 overwrite = false;
48 this.serviceType = serviceType;
49 descriptors = new List<ComponentDescriptor<S>>();
52 internal bool Overwrite
54 get { return overwrite; }
57 /// <summary>
58 /// With the overwrite.
59 /// </summary>
60 /// <returns></returns>
61 public ComponentRegistration<S> OverWrite()
63 overwrite = true;
64 return this;
67 /// <summary>
68 /// With the name.
69 /// </summary>
70 /// <param name="name">The name.</param>
71 /// <returns></returns>
72 public ComponentRegistration<S> Named(String name)
74 if (this.name != null)
76 String message = String.Format("This component has " +
77 "already been assigned name '{0}'", this.name);
79 throw new ComponentRegistrationException(message);
82 this.name = name;
83 return this;
86 public ComponentRegistration<S> ImplementedBy<C>()
88 return ImplementedBy(typeof(C));
91 public ComponentRegistration<S> ImplementedBy(Type type)
93 if (classType != null)
95 String message = String.Format("This component has " +
96 "already been assigned implementation {0}", classType.FullName);
97 throw new ComponentRegistrationException(message);
100 classType = type;
101 return this;
104 /// <summary>
105 /// With the instance.
106 /// </summary>
107 /// <param name="instance">The instance.</param>
108 /// <returns></returns>
109 public ComponentRegistration<S> Instance(S instance)
111 return AddDescriptor(new ComponentInstanceDescriptior<S>(instance));
114 /// <summary>
115 /// Gets the proxy.
116 /// </summary>
117 /// <value>The proxy.</value>
118 public Proxy.ProxyGroup<S> Proxy
120 get { return new Proxy.ProxyGroup<S>(this); }
123 /// <summary>
124 /// Gets the with lifestyle.
125 /// </summary>
126 /// <value>The with lifestyle.</value>
127 public Lifestyle.LifestyleGroup<S> LifeStyle
129 get { return new Lifestyle.LifestyleGroup<S>(this); }
132 /// <summary>
133 /// With the activator.
134 /// </summary>
135 /// <returns></returns>
136 public ComponentRegistration<S> Activator<A>() where A : IComponentActivator
138 return AddAttributeDescriptor("componentActivatorType", typeof(A).AssemblyQualifiedName);
141 /// <summary>
142 /// With the extended properties.
143 /// </summary>
144 /// <param name="properties">The properties.</param>
145 /// <returns></returns>
146 public ComponentRegistration<S> ExtendedProperties(params Property[] properties)
148 return AddDescriptor(new ExtendedPropertiesDescriptor<S>(properties));
151 /// <summary>
152 /// With the extended properties.
153 /// </summary>
154 /// <param name="anonymous">The properties.</param>
155 /// <returns></returns>
156 public ComponentRegistration<S> ExtendedProperties(object anonymous)
158 return AddDescriptor(new ExtendedPropertiesDescriptor<S>(anonymous));
161 /// <summary>
162 /// With the custom dependencies.
163 /// </summary>
164 /// <param name="dependencies">The dependencies.</param>
165 /// <returns></returns>
166 public ComponentRegistration<S> CustomDependencies(params Property[] dependencies)
168 return AddDescriptor(new CustomDependencyDescriptor<S>(dependencies));
171 /// <summary>
172 /// With the custom dependencies.
173 /// </summary>
174 /// <param name="dependencies">The dependencies.</param>
175 /// <returns></returns>
176 public ComponentRegistration<S> CustomDependencies(IDictionary dependencies)
178 return AddDescriptor(new CustomDependencyDescriptor<S>(dependencies));
181 /// <summary>
182 /// With the custom dependencies.
183 /// </summary>
184 /// <param name="anonymous">The dependencies.</param>
185 /// <returns></returns>
186 public ComponentRegistration<S> CustomDependencies(object anonymous)
188 return AddDescriptor(new CustomDependencyDescriptor<S>(anonymous));
191 /// <summary>
192 /// With the service overrides.
193 /// </summary>
194 /// <param name="overrides">The overrides.</param>
195 /// <returns></returns>
196 public ComponentRegistration<S> ServiceOverrides(params ServiceOverride[] overrides)
198 return AddDescriptor(new ServiceOverrideDescriptor<S>(overrides));
201 /// <summary>
202 /// With the service overrides.
203 /// </summary>
204 /// <param name="overrides">The overrides.</param>
205 /// <returns></returns>
206 public ComponentRegistration<S> ServiceOverrides(IDictionary overrides)
208 return AddDescriptor(new ServiceOverrideDescriptor<S>(overrides));
211 /// <summary>
212 /// With the service overrides.
213 /// </summary>
214 /// <param name="anonymous">The overrides.</param>
215 /// <returns></returns>
216 public ComponentRegistration<S> ServiceOverrides(object anonymous)
218 return AddDescriptor(new ServiceOverrideDescriptor<S>(anonymous));
221 /// <summary>
222 /// With the configuration parameters.
223 /// </summary>
224 /// <param name="parameters">The parameters.</param>
225 /// <returns></returns>
226 public ComponentRegistration<S> Parameters(params Parameter[] parameters)
228 return AddDescriptor(new ParametersDescriptor<S>(parameters));
231 /// <summary>
232 /// With the interceptors.
233 /// </summary>
234 /// <param name="interceptors">The interceptors.</param>
235 /// <returns></returns>
236 public Interceptor.InterceptorGroup<S> Interceptors(
237 params InterceptorReference[] interceptors)
239 return new Interceptor.InterceptorGroup<S>(this, interceptors);
242 /// <summary>
243 /// Ases the startable.
244 /// </summary>
245 /// <returns></returns>
246 public ComponentRegistration<S> Startable()
248 return AddDescriptor(new ExtendedPropertiesDescriptor<S>(
249 Property.ForKey("startable").Eq(true)));
252 /// <summary>
253 /// Registers this component with the <see cref="IKernel"/>.
254 /// </summary>
255 /// <param name="kernel">The kernel.</param>
256 void IComponentRegistration.Register(IKernel kernel)
258 if (componentModel == null)
260 InitializeDefaults();
261 componentModel = BuildComponentModel(kernel);
262 kernel.AddCustomComponent(componentModel);
266 /// <summary>
267 /// Builds the component model.
268 /// </summary>
269 /// <returns></returns>
270 private ComponentModel BuildComponentModel(IKernel kernel)
272 IConfiguration configuration = EnsureComponentConfiguration(kernel);
273 foreach(ComponentDescriptor<S> descriptor in descriptors)
275 descriptor.ApplyToConfiguration(kernel, configuration);
278 ComponentModel model = kernel.ComponentModelBuilder.BuildModel(
279 name, serviceType, classType, null);
280 foreach(ComponentDescriptor<S> descriptor in descriptors)
282 descriptor.ApplyToModel(kernel, model);
285 return model;
288 /// <summary>
289 /// Adds the attribute descriptor.
290 /// </summary>
291 /// <param name="key">The key.</param>
292 /// <param name="value">The value.</param>
293 /// <returns></returns>
294 public ComponentRegistration<S> AddAttributeDescriptor(string key, string value)
296 AddDescriptor(new AttributeDescriptor<S>(key, value));
297 return this;
300 /// <summary>
301 /// Adds the descriptor.
302 /// </summary>
303 /// <param name="descriptor">The descriptor.</param>
304 /// <returns></returns>
305 public ComponentRegistration<S> AddDescriptor(ComponentDescriptor<S> descriptor)
307 descriptor.Registration = this;
308 descriptors.Add(descriptor);
309 return this;
312 internal void AddParameter(IKernel kernel, ComponentModel model, String key, String value)
314 IConfiguration parameters = EnsureParametersConfiguration(kernel);
315 MutableConfiguration parameter = new MutableConfiguration(key, value);
316 parameters.Children.Add(parameter);
317 model.Parameters.Add(key, value);
320 internal void AddParameter(IKernel kernel, ComponentModel model, String key, IConfiguration value)
322 IConfiguration parameters = EnsureParametersConfiguration(kernel);
323 MutableConfiguration parameter = new MutableConfiguration(key);
324 parameter.Children.Add(value);
325 parameters.Children.Add(parameter);
326 model.Parameters.Add(key, value);
329 private void InitializeDefaults()
331 if (classType == null)
333 classType = serviceType;
336 if (String.IsNullOrEmpty(name))
338 name = classType.FullName;
342 private IConfiguration EnsureParametersConfiguration(IKernel kernel)
344 IConfiguration configuration = EnsureComponentConfiguration(kernel);
345 IConfiguration parameters = configuration.Children["parameters"];
346 if (parameters == null)
348 parameters = new MutableConfiguration("component");
349 configuration.Children.Add(parameters);
351 return parameters;
354 private IConfiguration EnsureComponentConfiguration(IKernel kernel)
356 IConfiguration configuration = kernel.ConfigurationStore.GetComponentConfiguration(name);
357 if (configuration == null)
359 configuration = new MutableConfiguration("component");
360 kernel.ConfigurationStore.AddComponentConfiguration(name, configuration);
362 return configuration;
366 public class ComponentRegistration : ComponentRegistration<object>
368 public ComponentRegistration(Type serviceType)
369 : base( serviceType )