Added ActAs to ComponentRegistration to simplify tagging the component registration.
[castle.git] / InversionOfControl / Castle.MicroKernel / Registration / ComponentRegistration.cs
blobb5e376e2fd130ca0ae6cc2688358b847f6e1c11e
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 /// Registration for a single component with the kernel.
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;
36 private bool registered;
38 /// <summary>
39 /// Initializes a new instance of the <see cref="ComponentRegistration{S}"/> class.
40 /// </summary>
41 public ComponentRegistration()
43 overwrite = false;
44 registered = false;
45 serviceType = typeof(S);
46 descriptors = new List<ComponentDescriptor<S>>();
49 /// <summary>
50 /// Initializes a new instance of the <see cref="ComponentRegistration{S}"/> class
51 /// with an existing <see cref="ComponentModel"/>.
52 /// </summary>
53 protected ComponentRegistration(ComponentModel componentModel) : this()
55 if (componentModel == null)
57 throw new ArgumentNullException("componentModel");
60 this.componentModel = componentModel;
61 name = componentModel.Name;
62 serviceType = componentModel.Service;
63 implementation = componentModel.Implementation;
66 public String Name
68 get { return name; }
71 public Type ServiceType
73 get { return serviceType; }
74 protected set { serviceType = value; }
77 public Type Implementation
79 get { return implementation; }
82 internal bool IsOverWrite
84 get { return overwrite; }
87 /// <summary>
88 /// With the overwrite.
89 /// </summary>
90 /// <returns></returns>
91 public ComponentRegistration<S> OverWrite()
93 overwrite = true;
94 return this;
97 /// <summary>
98 /// With the name.
99 /// </summary>
100 /// <param name="name">The name.</param>
101 /// <returns></returns>
102 public ComponentRegistration<S> Named(String name)
104 if (this.name != null)
106 String message = String.Format("This component has " +
107 "already been assigned name '{0}'", this.name);
109 throw new ComponentRegistrationException(message);
112 this.name = name;
113 return this;
116 public ComponentRegistration<S> ImplementedBy<C>()
118 return ImplementedBy(typeof(C));
121 public ComponentRegistration<S> ImplementedBy(Type type)
123 if (implementation != null)
125 String message = String.Format("This component has " +
126 "already been assigned implementation {0}", implementation.FullName);
127 throw new ComponentRegistrationException(message);
130 implementation = type;
131 return this;
134 /// <summary>
135 /// With the instance.
136 /// </summary>
137 /// <param name="instance">The instance.</param>
138 /// <returns></returns>
139 public ComponentRegistration<S> Instance(S instance)
141 if (instance == null)
143 throw new ArgumentNullException("instance");
146 ImplementedBy(instance.GetType());
147 return AddDescriptor(new ComponentInstanceDescriptior<S>(instance));
150 /// <summary>
151 /// Gets the proxy.
152 /// </summary>
153 /// <value>The proxy.</value>
154 public Proxy.ProxyGroup<S> Proxy
156 get { return new Proxy.ProxyGroup<S>(this); }
159 /// <summary>
160 /// Gets the with lifestyle.
161 /// </summary>
162 /// <value>The with lifestyle.</value>
163 public Lifestyle.LifestyleGroup<S> LifeStyle
165 get { return new Lifestyle.LifestyleGroup<S>(this); }
168 /// <summary>
169 /// With the activator.
170 /// </summary>
171 /// <returns></returns>
172 public ComponentRegistration<S> Activator<A>() where A : IComponentActivator
174 return AddAttributeDescriptor("componentActivatorType", typeof(A).AssemblyQualifiedName);
177 /// <summary>
178 /// With the extended properties.
179 /// </summary>
180 /// <param name="properties">The properties.</param>
181 /// <returns></returns>
182 public ComponentRegistration<S> ExtendedProperties(params Property[] properties)
184 return AddDescriptor(new ExtendedPropertiesDescriptor<S>(properties));
187 /// <summary>
188 /// With the extended properties.
189 /// </summary>
190 /// <param name="anonymous">The properties.</param>
191 /// <returns></returns>
192 public ComponentRegistration<S> ExtendedProperties(object anonymous)
194 return AddDescriptor(new ExtendedPropertiesDescriptor<S>(anonymous));
197 /// <summary>
198 /// With the custom dependencies.
199 /// </summary>
200 /// <param name="dependencies">The dependencies.</param>
201 /// <returns></returns>
202 public ComponentRegistration<S> CustomDependencies(params Property[] dependencies)
204 return AddDescriptor(new CustomDependencyDescriptor<S>(dependencies));
207 /// <summary>
208 /// With the custom dependencies.
209 /// </summary>
210 /// <param name="dependencies">The dependencies.</param>
211 /// <returns></returns>
212 public ComponentRegistration<S> CustomDependencies(IDictionary dependencies)
214 return AddDescriptor(new CustomDependencyDescriptor<S>(dependencies));
217 /// <summary>
218 /// With the custom dependencies.
219 /// </summary>
220 /// <param name="anonymous">The dependencies.</param>
221 /// <returns></returns>
222 public ComponentRegistration<S> CustomDependencies(object anonymous)
224 return AddDescriptor(new CustomDependencyDescriptor<S>(anonymous));
227 /// <summary>
228 /// With the service overrides.
229 /// </summary>
230 /// <param name="overrides">The overrides.</param>
231 /// <returns></returns>
232 public ComponentRegistration<S> ServiceOverrides(params ServiceOverride[] overrides)
234 return AddDescriptor(new ServiceOverrideDescriptor<S>(overrides));
237 /// <summary>
238 /// With the service overrides.
239 /// </summary>
240 /// <param name="overrides">The overrides.</param>
241 /// <returns></returns>
242 public ComponentRegistration<S> ServiceOverrides(IDictionary overrides)
244 return AddDescriptor(new ServiceOverrideDescriptor<S>(overrides));
247 /// <summary>
248 /// With the service overrides.
249 /// </summary>
250 /// <param name="anonymous">The overrides.</param>
251 /// <returns></returns>
252 public ComponentRegistration<S> ServiceOverrides(object anonymous)
254 return AddDescriptor(new ServiceOverrideDescriptor<S>(anonymous));
257 /// <summary>
258 /// With the configuration parameters.
259 /// </summary>
260 /// <param name="parameters">The parameters.</param>
261 /// <returns></returns>
262 public ComponentRegistration<S> Parameters(params Parameter[] parameters)
264 return AddDescriptor(new ParametersDescriptor<S>(parameters));
267 /// <summary>
268 /// With the configuration.
269 /// </summary>
270 /// <param name="configNodes">The config nodes.</param>
271 /// <returns></returns>
272 public ComponentRegistration<S> Configuration(params Node[] configNodes)
274 return AddDescriptor( new ConfigurationDescriptor<S>(configNodes));
277 /// <summary>
278 /// With the interceptors.
279 /// </summary>
280 /// <param name="interceptors">The interceptors.</param>
281 /// <returns></returns>
282 public Interceptor.InterceptorGroup<S> Interceptors(
283 params InterceptorReference[] interceptors)
285 return new Interceptor.InterceptorGroup<S>(this, interceptors);
288 /// <summary>
289 /// Ases the startable.
290 /// </summary>
291 /// <returns></returns>
292 public ComponentRegistration<S> Startable()
294 return AddDescriptor(new ExtendedPropertiesDescriptor<S>(
295 Property.ForKey("startable").Eq(true)));
298 /// <summary>
299 /// Marks the components with one or more actors.
300 /// </summary>
301 /// <param name="actors">The component actors.</param>
302 /// <returns></returns>
303 public ComponentRegistration<S> ActAs(params object[] actors)
305 foreach (object actor in actors)
307 if (actor != null)
309 CustomDependencies(Property.ForKey(Guid.NewGuid().ToString()).Eq(actor));
312 return this;
315 /// <summary>
316 /// Registers this component with the <see cref="IKernel"/>.
317 /// </summary>
318 /// <param name="kernel">The kernel.</param>
319 void IRegistration.Register(IKernel kernel)
321 if (!registered)
323 registered = true;
324 InitializeDefaults();
326 IConfiguration configuration = EnsureComponentConfiguration(kernel);
327 foreach(ComponentDescriptor<S> descriptor in descriptors)
329 descriptor.ApplyToConfiguration(kernel, configuration);
332 if (componentModel == null)
334 componentModel = kernel.ComponentModelBuilder.BuildModel(
335 name, serviceType, implementation, null);
338 foreach (ComponentDescriptor<S> descriptor in descriptors)
340 descriptor.ApplyToModel(kernel, componentModel);
343 if (!kernel.HasComponent(name))
345 kernel.AddCustomComponent(componentModel);
350 /// <summary>
351 /// Adds the attribute descriptor.
352 /// </summary>
353 /// <param name="key">The key.</param>
354 /// <param name="value">The value.</param>
355 /// <returns></returns>
356 public ComponentRegistration<S> AddAttributeDescriptor(string key, string value)
358 AddDescriptor(new AttributeDescriptor<S>(key, value));
359 return this;
362 /// <summary>
363 /// Adds the descriptor.
364 /// </summary>
365 /// <param name="descriptor">The descriptor.</param>
366 /// <returns></returns>
367 public ComponentRegistration<S> AddDescriptor(ComponentDescriptor<S> descriptor)
369 descriptor.Registration = this;
370 descriptors.Add(descriptor);
371 return this;
374 internal void AddParameter(IKernel kernel, ComponentModel model, String key, String value)
376 IConfiguration parameters = EnsureParametersConfiguration(kernel);
377 MutableConfiguration parameter = new MutableConfiguration(key, value);
378 parameters.Children.Add(parameter);
379 model.Parameters.Add(key, value);
382 internal void AddParameter(IKernel kernel, ComponentModel model, String key, IConfiguration value)
384 IConfiguration parameters = EnsureParametersConfiguration(kernel);
385 MutableConfiguration parameter = new MutableConfiguration(key);
386 parameter.Children.Add(value);
387 parameters.Children.Add(parameter);
388 model.Parameters.Add(key, value);
391 private void InitializeDefaults()
393 if (implementation == null)
395 implementation = serviceType;
398 if (String.IsNullOrEmpty(name))
400 name = implementation.FullName;
404 private IConfiguration EnsureParametersConfiguration(IKernel kernel)
406 IConfiguration configuration = EnsureComponentConfiguration(kernel);
407 IConfiguration parameters = configuration.Children["parameters"];
408 if (parameters == null)
410 parameters = new MutableConfiguration("component");
411 configuration.Children.Add(parameters);
413 return parameters;
416 private IConfiguration EnsureComponentConfiguration(IKernel kernel)
418 IConfiguration configuration = kernel.ConfigurationStore.GetComponentConfiguration(name);
419 if (configuration == null)
421 configuration = new MutableConfiguration("component");
422 kernel.ConfigurationStore.AddComponentConfiguration(name, configuration);
424 return configuration;
428 #region Nested Type: ComponentRegistration
430 public class ComponentRegistration : ComponentRegistration<object>
432 public ComponentRegistration()
436 public ComponentRegistration(Type serviceType)
438 ServiceType = serviceType;
441 public ComponentRegistration(ComponentModel componentModel)
442 : base(componentModel)
446 public ComponentRegistration For(Type serviceType)
448 if (ServiceType != null)
450 String message = String.Format("This component has " +
451 "already been assigned service type {0}", ServiceType.FullName);
452 throw new ComponentRegistrationException(message);
455 ServiceType = serviceType;
456 return this;
460 #endregion