Added non-generic registration interface to IKernel and IWindsor to accommodate dynam...
[castle.git] / InversionOfControl / Castle.MicroKernel / Registration / ComponentRegistration.cs
blobfb9c9a8e499095cc7dc463dc079f283c89388b3e
1 // Copyright 2004-2007 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;
23 /// <summary>
24 ///
25 /// </summary>
26 /// <typeparam name="S">The service type</typeparam>
27 /// <typeparam name="T">The chaining type</typeparam>
28 public class ComponentRegistration<S,T>
30 private String name;
31 private bool overwrite;
32 private readonly IKernel kernel;
33 private readonly Type serviceType;
34 private Type classType;
35 private readonly T chain;
36 private readonly List<ComponentDescriptor<S,T>> descriptors;
37 private ComponentModel componentModel;
39 /// <summary>
40 /// Initializes a new instance of the <see cref="ComponentRegistration{S,T}"/> class.
41 /// </summary>
42 /// <param name="kernel">The kernel.</param>
43 /// <param name="chain">The chain</param>
44 public ComponentRegistration(IKernel kernel, T chain)
45 : this(typeof(S), kernel, chain)
49 protected ComponentRegistration(Type serviceType, IKernel kernel, T chain)
51 overwrite = false;
52 this.kernel = kernel;
53 this.chain = chain;
54 this.serviceType = serviceType;
55 descriptors = new List<ComponentDescriptor<S, T>>();
58 internal bool Overwrite
60 get { return overwrite; }
63 /// <summary>
64 /// With the overwrite.
65 /// </summary>
66 /// <returns></returns>
67 public ComponentRegistration<S,T> WithOverwrite()
69 overwrite = true;
70 return this;
73 /// <summary>
74 /// With the name.
75 /// </summary>
76 /// <param name="name">The name.</param>
77 /// <returns></returns>
78 public ComponentRegistration<S,T> WithName(String name)
80 if (this.name != null)
82 String message = String.Format("This component has " +
83 "already been assigned name '{0}'", this.name);
85 throw new ComponentRegistrationException(message);
88 this.name = name;
89 return this;
92 public ComponentRegistration<S, T> WithImplementation<C>()
94 if (classType != null)
96 String message = String.Format("This component has " +
97 "already been assigned implementation {0}", classType.FullName);
99 throw new ComponentRegistrationException(message);
102 classType = typeof(C);
103 return this;
106 /// <summary>
107 /// With the instance.
108 /// </summary>
109 /// <param name="instance">The instance.</param>
110 /// <returns></returns>
111 public ComponentRegistration<S,T> WithInstance(S instance)
113 return AddDescriptor(new ComponentInstanceDescriptior<S,T>(instance));
116 /// <summary>
117 /// Gets the proxy.
118 /// </summary>
119 /// <value>The proxy.</value>
120 public Proxy.ProxyGroup<S,T> Proxy
122 get { return new Proxy.ProxyGroup<S,T>(this); }
125 /// <summary>
126 /// Gets the with lifestyle.
127 /// </summary>
128 /// <value>The with lifestyle.</value>
129 public Lifestyle.LifestyleGroup<S,T> WithLifestyle
131 get { return new Lifestyle.LifestyleGroup<S,T>(this); }
134 /// <summary>
135 /// With the activator.
136 /// </summary>
137 /// <returns></returns>
138 public ComponentRegistration<S,T> WithActivator<A>() where A : IComponentActivator
140 return AddAttributeDescriptor("componentActivatorType", typeof(A).AssemblyQualifiedName);
143 /// <summary>
144 /// With the extended properties.
145 /// </summary>
146 /// <param name="properties">The properties.</param>
147 /// <returns></returns>
148 public ComponentRegistration<S,T> WithExtendedProperties(params Property[] properties)
150 return AddDescriptor(new ExtendedPropertiesDescriptor<S,T>(properties));
153 /// <summary>
154 /// With the extended properties.
155 /// </summary>
156 /// <param name="anonymous">The properties.</param>
157 /// <returns></returns>
158 public ComponentRegistration<S, T> WithExtendedProperties(object anonymous)
160 return AddDescriptor(new ExtendedPropertiesDescriptor<S, T>(anonymous));
163 /// <summary>
164 /// With the custom dependencies.
165 /// </summary>
166 /// <param name="dependencies">The dependencies.</param>
167 /// <returns></returns>
168 public ComponentRegistration<S,T> WithCustomDependencies(params Property[] dependencies)
170 return AddDescriptor(new CustomDependencyDescriptor<S,T>(dependencies));
173 /// <summary>
174 /// With the custom dependencies.
175 /// </summary>
176 /// <param name="dependencies">The dependencies.</param>
177 /// <returns></returns>
178 public ComponentRegistration<S,T> WithCustomDependencies(IDictionary dependencies)
180 return AddDescriptor(new CustomDependencyDescriptor<S,T>(dependencies));
183 /// <summary>
184 /// With the custom dependencies.
185 /// </summary>
186 /// <param name="anonymous">The dependencies.</param>
187 /// <returns></returns>
188 public ComponentRegistration<S, T> WithCustomDependencies(object anonymous)
190 return AddDescriptor(new CustomDependencyDescriptor<S, T>(anonymous));
193 /// <summary>
194 /// With the service overrides.
195 /// </summary>
196 /// <param name="overrides">The overrides.</param>
197 /// <returns></returns>
198 public ComponentRegistration<S,T> WithServiceOverrides(params ServiceOverride[] overrides)
200 return AddDescriptor(new ServiceOverrideDescriptor<S,T>(overrides));
203 /// <summary>
204 /// With the service overrides.
205 /// </summary>
206 /// <param name="overrides">The overrides.</param>
207 /// <returns></returns>
208 public ComponentRegistration<S,T> WithServiceOverrides(IDictionary overrides)
210 return AddDescriptor(new ServiceOverrideDescriptor<S,T>(overrides));
213 /// <summary>
214 /// With the service overrides.
215 /// </summary>
216 /// <param name="anonymous">The overrides.</param>
217 /// <returns></returns>
218 public ComponentRegistration<S, T> WithServiceOverrides(object anonymous)
220 return AddDescriptor(new ServiceOverrideDescriptor<S, T>(anonymous));
223 /// <summary>
224 /// With the interceptors.
225 /// </summary>
226 /// <param name="interceptors">The interceptors.</param>
227 /// <returns></returns>
228 public Interceptor.InterceptorGroup<S,T> WithInterceptors(
229 params InterceptorReference[] interceptors)
231 return new Interceptor.InterceptorGroup<S,T>(this, interceptors);
234 /// <summary>
235 /// Ases the startable.
236 /// </summary>
237 /// <returns></returns>
238 public ComponentRegistration<S,T> AsStartable()
240 return AddDescriptor(new ExtendedPropertiesDescriptor<S,T>(
241 Property.WithKey("startable").Eq(true)));
244 /// <summary>
245 /// Registers the current component and add another.
246 /// </summary>
247 /// <typeparam name="SS"></typeparam>
248 /// <returns></returns>
249 public ComponentRegistration<SS, T> AddComponentEx<SS>()
251 Register();
252 return new ComponentRegistration<SS, T>(kernel, chain);
255 /// <summary>
256 /// Registers this instance.
257 /// </summary>
258 /// <returns></returns>
259 public T Register()
261 if (componentModel == null)
263 InitializeDefaults();
264 componentModel = BuildComponentModel();
265 kernel.AddCustomComponent(componentModel);
267 return chain;
270 /// <summary>
271 /// Builds the component model.
272 /// </summary>
273 /// <returns></returns>
274 private ComponentModel BuildComponentModel()
276 IConfiguration configuration = EnsureComponentConfiguration();
277 foreach(ComponentDescriptor<S,T> descriptor in descriptors)
279 descriptor.ApplyToConfiguration(configuration);
282 ComponentModel model = kernel.ComponentModelBuilder.BuildModel(
283 name, serviceType, classType, null);
284 foreach(ComponentDescriptor<S,T> descriptor in descriptors)
286 descriptor.ApplyToModel(model);
289 return model;
292 /// <summary>
293 /// Adds the attribute descriptor.
294 /// </summary>
295 /// <param name="name">The name.</param>
296 /// <param name="value">The value.</param>
297 /// <returns></returns>
298 public ComponentRegistration<S,T> AddAttributeDescriptor(string name, string value)
300 AddDescriptor(new AttributeDescriptor<S,T>(name, value));
301 return this;
304 /// <summary>
305 /// Adds the descriptor.
306 /// </summary>
307 /// <param name="descriptor">The descriptor.</param>
308 /// <returns></returns>
309 public ComponentRegistration<S,T> AddDescriptor(ComponentDescriptor<S,T> descriptor)
311 descriptor.Registration = this;
312 descriptors.Add(descriptor);
313 return this;
316 internal void AddParameter(ComponentModel model, String name, String value)
318 IConfiguration configuration = EnsureComponentConfiguration();
319 IConfiguration parameters = configuration.Children["parameters"];
320 if (parameters == null)
322 parameters = new MutableConfiguration("component");
323 configuration.Children.Add(parameters);
326 MutableConfiguration reference = new MutableConfiguration(name, value);
327 parameters.Children.Add(reference);
328 model.Parameters.Add(name, value);
331 private void InitializeDefaults()
333 if (classType == null)
335 classType = serviceType;
338 if (String.IsNullOrEmpty(name))
340 name = classType.FullName;
344 private IConfiguration EnsureComponentConfiguration()
346 IConfiguration configuration = kernel.ConfigurationStore.GetComponentConfiguration(name);
347 if (configuration == null)
349 configuration = new MutableConfiguration("component");
350 kernel.ConfigurationStore.AddComponentConfiguration(name, configuration);
352 return configuration;
356 public class ComponentRegistration<T> : ComponentRegistration<object, T>
358 public ComponentRegistration(Type serviceType, IKernel kernel, T chain)
359 : base( serviceType, kernel, chain)