Supporting dynamically genereted signed assemblies
[castle.git] / InversionOfControl / Castle.Windsor / WindsorContainer.cs
blob2c737c87cd67020c2c151c1bc39673d6e3ae1a65
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.Windsor
17 using System;
18 using System.Collections;
20 using Castle.Core;
21 using Castle.MicroKernel;
22 using Castle.Windsor.Configuration;
23 using Castle.Windsor.Configuration.Interpreters;
25 /// <summary>
26 /// Implementation of <see cref="IWindsorContainer"/>
27 /// which delegates to <see cref="IKernel"/> implementation.
28 /// </summary>
29 [Serializable]
30 public class WindsorContainer : MarshalByRefObject, IWindsorContainer
32 #region Fields
34 private readonly string name = Guid.NewGuid().ToString();
35 private readonly IDictionary childContainers = Hashtable.Synchronized(new Hashtable());
37 private IKernel kernel;
38 private IWindsorContainer parent;
39 private IComponentsInstaller installer;
41 #endregion
43 #region Constructors
45 /// <summary>
46 /// Constructs a container without any external
47 /// configuration reference
48 /// </summary>
49 public WindsorContainer() : this(new DefaultKernel(), new Installer.DefaultComponentInstaller())
53 /// <summary>
54 /// Constructs a container using the specified
55 /// <see cref="IConfigurationStore"/> implementation.
56 /// </summary>
57 /// <param name="store">The instance of an <see cref="IConfigurationStore"/> implementation.</param>
58 public WindsorContainer(IConfigurationStore store) : this()
60 kernel.ConfigurationStore = store;
62 RunInstaller();
65 /// <summary>
66 /// Constructs a container using the specified
67 /// <see cref="IConfigurationInterpreter"/> implementation.
68 /// </summary>
69 /// <param name="interpreter">The instance of an <see cref="IConfigurationInterpreter"/> implementation.</param>
70 public WindsorContainer(IConfigurationInterpreter interpreter) : this()
72 if (interpreter == null) throw new ArgumentNullException("interpreter");
74 interpreter.ProcessResource(interpreter.Source, kernel.ConfigurationStore);
76 RunInstaller();
79 /// <summary>
80 /// Initializes a new instance of the <see cref="WindsorContainer"/> class.
81 /// </summary>
82 /// <param name="interpreter">The interpreter.</param>
83 /// <param name="environmentInfo">The environment info.</param>
84 public WindsorContainer(IConfigurationInterpreter interpreter, IEnvironmentInfo environmentInfo) : this()
86 if (interpreter == null) throw new ArgumentNullException("interpreter");
87 if (environmentInfo == null) throw new ArgumentNullException("environmentInfo");
89 interpreter.EnvironmentName = environmentInfo.GetEnvironmentName();
90 interpreter.ProcessResource(interpreter.Source, kernel.ConfigurationStore);
92 RunInstaller();
95 /// <summary>
96 /// Initializes a new instance of the <see cref="WindsorContainer"/> class using a
97 /// xml file to configure it.
98 /// <para>
99 /// Equivalent to the use of <c>new WindsorContainer(new XmlInterpreter(xmlFile))</c>
100 /// </para>
101 /// </summary>
102 /// <param name="xmlFile">The XML file.</param>
103 public WindsorContainer(String xmlFile) : this(new XmlInterpreter(xmlFile))
107 /// <summary>
108 /// Constructs a container using the specified <see cref="IKernel"/>
109 /// implementation. Rarely used.
110 /// </summary>
111 /// <remarks>
112 /// This constructs sets the Kernel.ProxyFactory property to
113 /// <see cref="Proxy.DefaultProxyFactory"/>
114 /// </remarks>
115 /// <param name="kernel">Kernel instance</param>
116 /// <param name="installer">Installer instance</param>
117 public WindsorContainer(IKernel kernel, IComponentsInstaller installer) : this(Guid.NewGuid().ToString(), kernel, installer)
121 /// <summary>
122 /// Constructs a container using the specified <see cref="IKernel"/>
123 /// implementation. Rarely used.
124 /// </summary>
125 /// <remarks>
126 /// This constructs sets the Kernel.ProxyFactory property to
127 /// <see cref="Proxy.DefaultProxyFactory"/>
128 /// </remarks>
129 /// <param name="name">Container's name</param>
130 /// <param name="kernel">Kernel instance</param>
131 /// <param name="installer">Installer instance</param>
132 public WindsorContainer(String name, IKernel kernel, IComponentsInstaller installer)
134 if (name == null) throw new ArgumentNullException("name");
135 if (kernel == null) throw new ArgumentNullException("kernel");
136 if (installer == null) throw new ArgumentNullException("installer");
138 this.kernel = kernel;
139 this.kernel.ProxyFactory = new Proxy.DefaultProxyFactory();
141 this.installer = installer;
144 /// <summary>
145 /// Constructs with a given <see cref="IProxyFactory"/>.
146 /// </summary>
147 /// <param name="proxyFactory">A instance of an <see cref="IProxyFactory"/>.</param>
148 public WindsorContainer(IProxyFactory proxyFactory)
150 if (proxyFactory == null) throw new ArgumentNullException("proxyFactory");
152 kernel = new DefaultKernel(proxyFactory);
154 installer = new Installer.DefaultComponentInstaller();
157 /// <summary>
158 /// Constructs a container assigning a parent container
159 /// before starting the dependency resolution.
160 /// </summary>
161 /// <param name="parent">The instance of an <see cref="IWindsorContainer"/></param>
162 /// <param name="interpreter">The instance of an <see cref="IConfigurationInterpreter"/> implementation</param>
163 public WindsorContainer(IWindsorContainer parent, IConfigurationInterpreter interpreter) : this()
165 if (parent == null) throw new ArgumentNullException("parent");
166 if (interpreter == null) throw new ArgumentNullException("interpreter");
168 parent.AddChildContainer(this);
170 interpreter.ProcessResource(interpreter.Source, kernel.ConfigurationStore);
172 RunInstaller();
175 /// <summary>
176 /// Initializes a new instance of the <see cref="WindsorContainer"/> class.
177 /// </summary>
178 /// <param name="name">The container's name.</param>
179 /// <param name="parent">The parent.</param>
180 /// <param name="interpreter">The interpreter.</param>
181 public WindsorContainer(string name, IWindsorContainer parent, IConfigurationInterpreter interpreter) : this()
183 if (name == null) throw new ArgumentNullException("name");
184 if (parent == null) throw new ArgumentNullException("parent");
185 if (interpreter == null) throw new ArgumentNullException("interpreter");
187 this.name = name;
189 parent.AddChildContainer(this);
191 interpreter.ProcessResource(interpreter.Source, kernel.ConfigurationStore);
193 RunInstaller();
196 #endregion
198 #region IWindsorContainer Members
200 /// <summary>
201 /// Gets the container's name
202 /// </summary>
203 /// <remarks>
204 /// Only useful when child containers are being used
205 /// </remarks>
206 /// <value>The container's name.</value>
207 public string Name
209 get { return name; }
212 /// <summary>
213 /// Returns the inner instance of the MicroKernel
214 /// </summary>
215 public virtual IKernel Kernel
217 get { return kernel; }
220 /// <summary>
221 /// Gets or sets the parent container if this instance
222 /// is a sub container.
223 /// </summary>
224 public virtual IWindsorContainer Parent
226 get { return parent; }
229 if( value == null )
231 if (parent != null)
233 parent.RemoveChildContainer(this);
234 parent = null;
237 else
239 if (value != parent)
241 parent = value;
242 parent.AddChildContainer(this);
248 /// <summary>
249 /// Registers a facility within the kernel.
250 /// </summary>
251 /// <param name="key"></param>
252 /// <param name="facility"></param>
253 public virtual void AddFacility(String key, IFacility facility)
255 kernel.AddFacility(key, facility);
258 /// <summary>
259 /// Adds a component to be managed by the container
260 /// </summary>
261 /// <param name="key"></param>
262 /// <param name="classType"></param>
263 public virtual void AddComponent(String key, Type classType)
265 kernel.AddComponent(key, classType);
268 /// <summary>
269 /// Adds a component to be managed by the container
270 /// </summary>
271 /// <param name="key"></param>
272 /// <param name="serviceType"></param>
273 /// <param name="classType"></param>
274 public virtual void AddComponent(String key, Type serviceType, Type classType)
276 kernel.AddComponent(key, serviceType, classType);
279 /// <summary>
280 /// Adds a component to be managed by the container
281 /// </summary>
282 /// <param name="key">The key by which the component gets indexed.</param>
283 /// <param name="classType">The <see cref="Type"/> to manage.</param>
284 /// <param name="lifestyle">The <see cref="LifestyleType"/> with which to manage the component.</param>
285 public void AddComponentWithLifestyle(string key, Type classType, LifestyleType lifestyle)
287 kernel.AddComponent(key, classType, lifestyle, true);
290 /// <summary>
291 /// Adds a component to be managed by the container
292 /// </summary>
293 /// <param name="key">The key by which the component gets indexed.</param>
294 /// <param name="serviceType">The service <see cref="Type"/> that the component implements.</param>
295 /// <param name="classType">The <see cref="Type"/> to manage.</param>
296 /// <param name="lifestyle">The <see cref="LifestyleType"/> with which to manage the component.</param>
297 public void AddComponentWithLifestyle(string key, Type serviceType, Type classType, LifestyleType lifestyle)
299 kernel.AddComponent(key, serviceType, classType, lifestyle, true);
302 public virtual void AddComponentWithProperties(string key, Type classType, IDictionary extendedProperties)
304 kernel.AddComponentWithExtendedProperties(key, classType, extendedProperties);
307 public virtual void AddComponentWithProperties(string key, Type serviceType, Type classType,
308 IDictionary extendedProperties)
310 kernel.AddComponentWithExtendedProperties(key, serviceType, classType, extendedProperties);
313 /// <summary>
314 /// Returns a component instance by the key
315 /// </summary>
316 /// <param name="key"></param>
317 /// <returns></returns>
318 public virtual object Resolve(String key)
320 return kernel[key];
323 /// <summary>
324 /// Returns a component instance by the service
325 /// </summary>
326 /// <param name="service"></param>
327 /// <param name="arguments"></param>
328 /// <returns></returns>
329 public virtual object Resolve(Type service, IDictionary arguments)
331 return kernel.Resolve(service, arguments);
334 /// <summary>
335 /// Returns a component instance by the key
336 /// </summary>
337 /// <param name="key"></param>
338 /// <param name="arguments"></param>
339 /// <returns></returns>
340 public virtual object Resolve(String key, IDictionary arguments)
342 return kernel.Resolve(key, arguments);
345 /// <summary>
346 /// Returns a component instance by the service
347 /// </summary>
348 /// <param name="service"></param>
349 /// <returns></returns>
350 public virtual object Resolve(Type service)
352 return kernel[service];
355 /// <summary>
356 /// Shortcut to the method <see cref="Resolve(String)"/>
357 /// </summary>
358 public virtual object this[String key]
360 get { return Resolve(key); }
363 /// <summary>
364 /// Shortcut to the method <see cref="Resolve(Type)"/>
365 /// </summary>
366 public virtual object this[Type service]
368 get { return Resolve(service); }
371 #if DOTNET2
373 /// <summary>
374 /// Returns a component instance by the key
375 /// </summary>
376 /// <param name="key"></param>
377 /// <param name="service"></param>
378 /// <returns></returns>
379 public virtual object Resolve(String key, Type service)
381 return kernel.Resolve(key, service);
384 /// <summary>
385 ///
386 /// </summary>
387 /// <param name="key"></param>
388 /// <param name="service"></param>
389 /// <param name="arguments"></param>
390 /// <returns></returns>
391 public virtual object Resolve(String key, Type service, IDictionary arguments)
393 return kernel.Resolve(key, service, arguments);
396 /// <summary>
397 /// Returns a component instance by the service
398 /// </summary>
399 /// <typeparam name="T"></typeparam>
400 /// <param name="arguments"></param>
401 /// <returns></returns>
402 public T Resolve<T>(IDictionary arguments)
404 return (T) Resolve(typeof(T), arguments);
407 /// <summary>
408 /// Returns a component instance by the key
409 /// </summary>
410 /// <param name="key"></param>
411 /// <param name="arguments"></param>
412 /// <returns></returns>
413 public virtual T Resolve<T>(String key, IDictionary arguments)
415 return (T) Resolve(key, typeof(T), arguments);
418 /// <summary>
419 /// Returns a component instance by the service
420 /// </summary>
421 /// <typeparam name="T"></typeparam>
422 /// <returns></returns>
423 public T Resolve<T>()
425 return (T)Resolve(typeof(T));
428 /// <summary>
429 /// Returns a component instance by the key
430 /// </summary>
431 /// <param name="key"></param>
432 /// <returns></returns>
433 public virtual T Resolve<T>(String key)
435 return (T)Resolve(key, typeof(T));
437 #endif
439 /// <summary>
440 /// Releases a component instance
441 /// </summary>
442 /// <param name="instance"></param>
443 public virtual void Release(object instance)
445 kernel.ReleaseComponent(instance);
448 /// <summary>
449 /// Registers a subcontainer. The components exposed
450 /// by this container will be accessible from subcontainers.
451 /// </summary>
452 /// <param name="childContainer"></param>
453 public virtual void AddChildContainer(IWindsorContainer childContainer)
455 if (childContainer == null) throw new ArgumentNullException("childContainer");
457 if (!childContainers.Contains(childContainer.Name))
459 lock (childContainers.SyncRoot)
461 if (!childContainers.Contains(childContainer.Name))
463 kernel.AddChildKernel(childContainer.Kernel);
464 childContainers.Add(childContainer.Name, childContainer);
465 childContainer.Parent = this;
471 /// <summary>
472 /// Removes (unregisters) a subcontainer. The components exposed by this container
473 /// will no longer be accessible to the child container.
474 /// </summary>
475 /// <param name="childContainer"></param>
476 public virtual void RemoveChildContainer(IWindsorContainer childContainer)
478 if (childContainer == null) throw new ArgumentNullException("childContainer");
480 if (childContainers.Contains(childContainer.Name))
482 lock (childContainers.SyncRoot)
484 if (childContainers.Contains(childContainer.Name))
486 kernel.RemoveChildKernel(childContainer.Kernel);
487 childContainers.Remove(childContainer.Name);
488 childContainer.Parent = null;
494 /// <summary>
495 /// Gets a child container instance by name.
496 /// </summary>
497 /// <param name="name">The container's name.</param>
498 /// <returns>The child container instance or null</returns>
499 public IWindsorContainer GetChildContainer(string name)
501 return childContainers[name] as IWindsorContainer;
504 #endregion
506 #region IDisposable Members
508 /// <summary>
509 /// Executes Dispose on underlying <see cref="IKernel"/>
510 /// </summary>
511 public virtual void Dispose()
513 Parent = null;
514 childContainers.Clear();
515 kernel.Dispose();
518 #endregion
520 #region Protected Operations Members
522 public IComponentsInstaller Installer
524 get { return installer; }
527 protected virtual void RunInstaller()
529 if (installer != null)
531 installer.SetUp(this, kernel.ConfigurationStore);
535 #endregion