1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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
18 using System
.Collections
;
21 using Castle
.MicroKernel
;
22 using Castle
.MicroKernel
.Registration
;
23 using Castle
.Windsor
.Configuration
;
24 using Castle
.Windsor
.Configuration
.Interpreters
;
27 /// Implementation of <see cref="IWindsorContainer"/>
28 /// which delegates to <see cref="IKernel"/> implementation.
31 public class WindsorContainer
: MarshalByRefObject
, IWindsorContainer
35 private readonly string name
= Guid
.NewGuid().ToString();
36 private readonly IDictionary childContainers
= Hashtable
.Synchronized(new Hashtable());
38 private IKernel kernel
;
39 private IWindsorContainer parent
;
40 private IComponentsInstaller installer
;
47 /// Constructs a container without any external
48 /// configuration reference
50 public WindsorContainer() : this(new DefaultKernel(), new Installer
.DefaultComponentInstaller())
55 /// Constructs a container using the specified
56 /// <see cref="IConfigurationStore"/> implementation.
58 /// <param name="store">The instance of an <see cref="IConfigurationStore"/> implementation.</param>
59 public WindsorContainer(IConfigurationStore store
) : this()
61 kernel
.ConfigurationStore
= store
;
67 /// Constructs a container using the specified
68 /// <see cref="IConfigurationInterpreter"/> implementation.
70 /// <param name="interpreter">The instance of an <see cref="IConfigurationInterpreter"/> implementation.</param>
71 public WindsorContainer(IConfigurationInterpreter interpreter
) : this()
73 if (interpreter
== null) throw new ArgumentNullException("interpreter");
75 interpreter
.ProcessResource(interpreter
.Source
, kernel
.ConfigurationStore
);
81 /// Initializes a new instance of the <see cref="WindsorContainer"/> class.
83 /// <param name="interpreter">The interpreter.</param>
84 /// <param name="environmentInfo">The environment info.</param>
85 public WindsorContainer(IConfigurationInterpreter interpreter
, IEnvironmentInfo environmentInfo
) : this()
87 if (interpreter
== null) throw new ArgumentNullException("interpreter");
88 if (environmentInfo
== null) throw new ArgumentNullException("environmentInfo");
90 interpreter
.EnvironmentName
= environmentInfo
.GetEnvironmentName();
91 interpreter
.ProcessResource(interpreter
.Source
, kernel
.ConfigurationStore
);
97 /// Initializes a new instance of the <see cref="WindsorContainer"/> class using a
98 /// xml file to configure it.
100 /// Equivalent to the use of <c>new WindsorContainer(new XmlInterpreter(xmlFile))</c>
103 /// <param name="xmlFile">The XML file.</param>
104 public WindsorContainer(String xmlFile
) : this(new XmlInterpreter(xmlFile
))
109 /// Constructs a container using the specified <see cref="IKernel"/>
110 /// implementation. Rarely used.
113 /// This constructs sets the Kernel.ProxyFactory property to
114 /// <see cref="Proxy.DefaultProxyFactory"/>
116 /// <param name="kernel">Kernel instance</param>
117 /// <param name="installer">Installer instance</param>
118 public WindsorContainer(IKernel kernel
, IComponentsInstaller installer
) : this(Guid
.NewGuid().ToString(), kernel
, installer
)
123 /// Constructs a container using the specified <see cref="IKernel"/>
124 /// implementation. Rarely used.
127 /// This constructs sets the Kernel.ProxyFactory property to
128 /// <see cref="Proxy.DefaultProxyFactory"/>
130 /// <param name="name">Container's name</param>
131 /// <param name="kernel">Kernel instance</param>
132 /// <param name="installer">Installer instance</param>
133 public WindsorContainer(String name
, IKernel kernel
, IComponentsInstaller installer
)
135 if (name
== null) throw new ArgumentNullException("name");
136 if (kernel
== null) throw new ArgumentNullException("kernel");
137 if (installer
== null) throw new ArgumentNullException("installer");
140 this.kernel
= kernel
;
141 this.kernel
.ProxyFactory
= new Proxy
.DefaultProxyFactory();
142 this.installer
= installer
;
146 /// Constructs with a given <see cref="IProxyFactory"/>.
148 /// <param name="proxyFactory">A instance of an <see cref="IProxyFactory"/>.</param>
149 public WindsorContainer(IProxyFactory proxyFactory
)
151 if (proxyFactory
== null) throw new ArgumentNullException("proxyFactory");
153 kernel
= new DefaultKernel(proxyFactory
);
155 installer
= new Installer
.DefaultComponentInstaller();
159 /// Constructs a container assigning a parent container
160 /// before starting the dependency resolution.
162 /// <param name="parent">The instance of an <see cref="IWindsorContainer"/></param>
163 /// <param name="interpreter">The instance of an <see cref="IConfigurationInterpreter"/> implementation</param>
164 public WindsorContainer(IWindsorContainer parent
, IConfigurationInterpreter interpreter
) : this()
166 if (parent
== null) throw new ArgumentNullException("parent");
167 if (interpreter
== null) throw new ArgumentNullException("interpreter");
169 parent
.AddChildContainer(this);
171 interpreter
.ProcessResource(interpreter
.Source
, kernel
.ConfigurationStore
);
177 /// Initializes a new instance of the <see cref="WindsorContainer"/> class.
179 /// <param name="name">The container's name.</param>
180 /// <param name="parent">The parent.</param>
181 /// <param name="interpreter">The interpreter.</param>
182 public WindsorContainer(string name
, IWindsorContainer parent
, IConfigurationInterpreter interpreter
) : this()
184 if (name
== null) throw new ArgumentNullException("name");
185 if (parent
== null) throw new ArgumentNullException("parent");
186 if (interpreter
== null) throw new ArgumentNullException("interpreter");
190 parent
.AddChildContainer(this);
192 interpreter
.ProcessResource(interpreter
.Source
, kernel
.ConfigurationStore
);
199 #region IWindsorContainer Members
202 /// Gets the container's name
205 /// Only useful when child containers are being used
207 /// <value>The container's name.</value>
214 /// Returns the inner instance of the MicroKernel
216 public virtual IKernel Kernel
218 get { return kernel; }
222 /// Gets or sets the parent container if this instance
223 /// is a sub container.
225 public virtual IWindsorContainer Parent
227 get { return parent; }
234 parent
.RemoveChildContainer(this);
243 parent
.AddChildContainer(this);
250 /// Registers a facility within the kernel.
252 /// <param name="key"></param>
253 /// <param name="facility"></param>
254 public virtual IWindsorContainer
AddFacility(String key
, IFacility facility
)
256 kernel
.AddFacility(key
, facility
);
261 /// Adds a component to be managed by the container
263 /// <param name="key"></param>
264 /// <param name="classType"></param>
265 public virtual IWindsorContainer
AddComponent(String key
, Type classType
)
267 kernel
.AddComponent(key
, classType
);
272 /// Adds a component to be managed by the container
274 /// <param name="key"></param>
275 /// <param name="serviceType"></param>
276 /// <param name="classType"></param>
277 public virtual IWindsorContainer
AddComponent(String key
, Type serviceType
, Type classType
)
279 kernel
.AddComponent(key
, serviceType
, classType
);
284 /// Adds a component to be managed by the container
286 /// <param name="key">The key by which the component gets indexed.</param>
287 /// <param name="classType">The <see cref="Type"/> to manage.</param>
288 /// <param name="lifestyle">The <see cref="LifestyleType"/> with which to manage the component.</param>
289 public IWindsorContainer
AddComponentLifeStyle(string key
, Type classType
, LifestyleType lifestyle
)
291 kernel
.AddComponent(key
, classType
, lifestyle
, true);
296 /// Adds a component to be managed by the container
298 /// <param name="key">The key by which the component gets indexed.</param>
299 /// <param name="serviceType">The service <see cref="Type"/> that the component implements.</param>
300 /// <param name="classType">The <see cref="Type"/> to manage.</param>
301 /// <param name="lifestyle">The <see cref="LifestyleType"/> with which to manage the component.</param>
302 public IWindsorContainer
AddComponentLifeStyle(string key
, Type serviceType
, Type classType
, LifestyleType lifestyle
)
304 kernel
.AddComponent(key
, serviceType
, classType
, lifestyle
, true);
308 public virtual IWindsorContainer
AddComponentWithProperties(string key
, Type classType
, IDictionary extendedProperties
)
310 kernel
.AddComponentWithExtendedProperties(key
, classType
, extendedProperties
);
314 public virtual IWindsorContainer
AddComponentWithProperties(string key
, Type serviceType
, Type classType
,
315 IDictionary extendedProperties
)
317 kernel
.AddComponentWithExtendedProperties(key
, serviceType
, classType
, extendedProperties
);
322 /// Adds a component to be managed by the container.
323 /// The key to obtain the component will be the FullName of the type.
325 /// <typeparam name="T">The <see cref="Type"/> to manage.</typeparam>
326 public IWindsorContainer AddComponent
<T
>()
329 AddComponent(t
.FullName
, t
);
334 /// Adds a component to be managed by the container
336 /// <typeparam name="T">The <see cref="Type"/> to manage.</typeparam>
337 /// <param name="key">The key by which the component gets indexed.</param>
338 public IWindsorContainer AddComponent
<T
>(string key
)
340 AddComponent(key
, typeof(T
));
345 /// Adds a component to be managed by the container.
346 /// The key to obtain the component will be the FullName of the type.
348 /// <typeparam name="T">The <see cref="Type"/> to manage.</typeparam>
349 /// <param name="lifestyle">The <see cref="LifestyleType"/> with which to manage the component.</param>
350 public IWindsorContainer AddComponentLifeStyle
<T
>(LifestyleType lifestyle
)
353 AddComponentLifeStyle(t
.FullName
, t
, lifestyle
);
358 /// Adds a component to be managed by the container
360 /// <typeparam name="I">The service <see cref="Type"/> that the component implements.</typeparam>
361 /// <typeparam name="T">The <see cref="Type"/> to manage.</typeparam>
362 /// <param name="key">The key by which the component gets indexed.</param>
363 public IWindsorContainer AddComponent
<I
, T
>(string key
) where T
: class
365 AddComponent(key
, typeof(I
), typeof(T
));
370 /// Adds a component to be managed by the container
371 /// The key to obtain the component will be the FullName of the type.
373 /// <typeparam name="I">The service <see cref="Type"/> that the component implements.</typeparam>
374 /// <typeparam name="T">The <see cref="Type"/> to manage.</typeparam>
375 /// <param name="lifestyle">The <see cref="LifestyleType"/> with which to manage the component.</param>
376 public IWindsorContainer AddComponentLifeStyle
<I
, T
>(LifestyleType lifestyle
) where T
: class
379 AddComponentLifeStyle(t
.FullName
, typeof(I
), t
, lifestyle
);
384 /// Adds a component to be managed by the container
386 /// <typeparam name="T">The <see cref="Type"/> to manage.</typeparam>
387 /// <param name="key">The key by which the component gets indexed.</param>
388 /// <param name="lifestyle">The <see cref="LifestyleType"/> with which to manage the component.</param>
389 public IWindsorContainer AddComponentLifeStyle
<T
>(string key
, LifestyleType lifestyle
)
391 AddComponentLifeStyle(key
, typeof(T
), lifestyle
);
396 /// Adds a component to be managed by the container
397 /// The key to obtain the component will be the FullName of the type.
399 /// <typeparam name="I">The service <see cref="Type"/> that the component implements.</typeparam>
400 /// <typeparam name="T">The <see cref="Type"/> to manage.</typeparam>
401 public IWindsorContainer AddComponent
<I
, T
>() where T
: class
404 AddComponent(t
.FullName
, typeof(I
), t
);
409 /// Adds a component to be managed by the container
411 /// <typeparam name="I">The service <see cref="Type"/> that the component implements.</typeparam>
412 /// <typeparam name="T">The <see cref="Type"/> to manage.</typeparam>
413 /// <param name="key">The key by which the component gets indexed.</param>
414 /// <param name="lifestyle">The <see cref="LifestyleType"/> with which to manage the component.</param>
415 public IWindsorContainer AddComponentLifeStyle
<I
, T
>(string key
, LifestyleType lifestyle
) where T
: class
417 AddComponentLifeStyle(key
, typeof(I
), typeof(T
), lifestyle
);
422 /// Adds a concrete class as a component and specify the extended properties.
423 /// Used by facilities, mostly.
424 /// The key to obtain the component will be the FullName of the type.
426 /// <typeparam name="T"></typeparam>
427 /// <param name="extendedProperties"></param>
428 public IWindsorContainer AddComponentWithProperties
<T
>(IDictionary extendedProperties
)
431 AddComponentWithProperties(t
.FullName
, t
, extendedProperties
);
436 /// Adds a concrete class as a component and specify the extended properties.
437 /// Used by facilities, mostly.
439 /// <typeparam name="T"></typeparam>
440 /// <param name="key"></param>
441 /// <param name="extendedProperties"></param>
442 public IWindsorContainer AddComponentWithProperties
<T
>(string key
, IDictionary extendedProperties
)
444 AddComponentWithProperties(key
, typeof(T
), extendedProperties
);
449 /// Adds a concrete class and an interface
450 /// as a component and specify the extended properties.
451 /// Used by facilities, mostly.
452 /// The key to obtain the component will be the FullName of the type.
454 /// <typeparam name="I"></typeparam>
455 /// <typeparam name="T"></typeparam>
456 /// <param name="extendedProperties"></param>
457 public IWindsorContainer AddComponentLifeStyle
<I
, T
>(IDictionary extendedProperties
) where T
: class
460 AddComponentWithProperties(t
.FullName
, typeof(I
), t
, extendedProperties
);
465 /// Adds a concrete class and an interface
466 /// as a component and specify the extended properties.
467 /// Used by facilities, mostly.
469 /// <typeparam name="I"></typeparam>
470 /// <typeparam name="T"></typeparam>
471 /// <param name="key"></param>
472 /// <param name="extendedProperties"></param>
473 public IWindsorContainer AddComponentLifeStyle
<I
, T
>(string key
, IDictionary extendedProperties
) where T
: class
475 AddComponentWithProperties(key
, typeof(I
), typeof(T
), extendedProperties
);
480 /// Registers the components described by the <see cref="ComponentRegistration{S}"/>s
481 /// with the <see cref="IWindsorContainer"/>.
482 /// <param name="registrations">The component registrations.</param>
483 /// <returns>The container.</returns>
485 public IWindsorContainer
Register(params IRegistration
[] registrations
)
487 Kernel
.Register(registrations
);
492 /// Returns a component instance by the key
494 /// <param name="key"></param>
495 /// <returns></returns>
496 public virtual object Resolve(String key
)
502 /// Returns a component instance by the service
504 /// <param name="service"></param>
505 /// <param name="arguments"></param>
506 /// <returns></returns>
507 public virtual object Resolve(Type service
, IDictionary arguments
)
509 return kernel
.Resolve(service
, arguments
);
513 /// Returns a component instance by the service
515 /// <param name="service"></param>
516 /// <param name="argumentsAsAnonymousType"></param>
517 /// <returns></returns>
518 public virtual object Resolve(Type service
, object argumentsAsAnonymousType
)
520 return Resolve(service
, new ReflectionBasedDictionaryAdapter(argumentsAsAnonymousType
));
524 /// Returns a component instance by the key
526 /// <param name="key"></param>
527 /// <param name="arguments"></param>
528 /// <returns></returns>
529 public virtual object Resolve(String key
, IDictionary arguments
)
531 return kernel
.Resolve(key
, arguments
);
535 /// Returns a component instance by the key
537 /// <param name="key"></param>
538 /// <param name="argumentsAsAnonymousType"></param>
539 /// <returns></returns>
540 public virtual object Resolve(String key
, object argumentsAsAnonymousType
)
542 return Resolve(key
, new ReflectionBasedDictionaryAdapter(argumentsAsAnonymousType
));
546 /// Returns a component instance by the service
548 /// <param name="service"></param>
549 /// <returns></returns>
550 public virtual object Resolve(Type service
)
552 return kernel
[service
];
556 /// Resolve all valid components that match this type.
558 /// <typeparam name="T">The service type</typeparam>
559 public T
[] ResolveAll
<T
>()
561 return (T
[]) ResolveAll(typeof(T
));
565 public Array
ResolveAll(Type service
)
567 return kernel
.ResolveAll(service
, new Hashtable());
570 public Array
ResolveAll(Type service
, IDictionary arguments
)
572 return kernel
.ResolveAll(service
, arguments
);
575 public Array
ResolveAll(Type service
, object argumentsAsAnonymousType
)
577 return ResolveAll(service
, new ReflectionBasedDictionaryAdapter(argumentsAsAnonymousType
));
581 /// Resolve all valid components that match this type.
582 /// <typeparam name="T">The service type</typeparam>
583 /// <param name="arguments">Arguments to resolve the service</param>
585 public T
[] ResolveAll
<T
>(IDictionary arguments
)
587 return (T
[]) ResolveAll(typeof (T
), arguments
);
591 /// Resolve all valid components that match this type.
592 /// <typeparam name="T">The service type</typeparam>
593 /// <param name="argumentsAsAnonymousType">Arguments to resolve the service</param>
595 public T
[] ResolveAll
<T
>(object argumentsAsAnonymousType
)
597 return ResolveAll
<T
>(new ReflectionBasedDictionaryAdapter(argumentsAsAnonymousType
));
601 /// Shortcut to the method <see cref="Resolve(String)"/>
603 public virtual object this[String key
]
605 get { return Resolve(key); }
609 /// Shortcut to the method <see cref="Resolve(Type)"/>
611 public virtual object this[Type service
]
613 get { return Resolve(service); }
617 /// Returns a component instance by the key
619 /// <param name="key"></param>
620 /// <param name="service"></param>
621 /// <returns></returns>
622 public virtual object Resolve(String key
, Type service
)
624 return kernel
.Resolve(key
, service
);
628 /// Returns a component instance by the key
630 /// <param name="key"></param>
631 /// <param name="service"></param>
632 /// <param name="arguments"></param>
633 /// <returns></returns>
634 public virtual object Resolve(String key
, Type service
, IDictionary arguments
)
636 return kernel
.Resolve(key
, service
, arguments
);
640 /// Returns a component instance by the key
642 /// <param name="key"></param>
643 /// <param name="service"></param>
644 /// <param name="argumentsAsAnonymousType"></param>
645 /// <returns></returns>
646 public virtual object Resolve(String key
, Type service
, object argumentsAsAnonymousType
)
648 return Resolve(key
, service
, new ReflectionBasedDictionaryAdapter(argumentsAsAnonymousType
));
652 /// Returns a component instance by the service
654 /// <typeparam name="T"></typeparam>
655 /// <param name="arguments"></param>
656 /// <returns></returns>
657 public T Resolve
<T
>(IDictionary arguments
)
659 return (T
) Resolve(typeof(T
), arguments
);
663 /// Returns a component instance by the service
665 /// <typeparam name="T"></typeparam>
666 /// <param name="argumentsAsAnonymousType"></param>
667 /// <returns></returns>
668 public T Resolve
<T
>(object argumentsAsAnonymousType
)
670 return Resolve
<T
>(new ReflectionBasedDictionaryAdapter(argumentsAsAnonymousType
));
674 /// Returns a component instance by the key
676 /// <param name="key"></param>
677 /// <param name="arguments"></param>
678 /// <returns></returns>
679 public virtual T Resolve
<T
>(String key
, IDictionary arguments
)
681 return (T
) Resolve(key
, typeof(T
), arguments
);
685 /// Returns a component instance by the key
687 /// <param name="key"></param>
688 /// <param name="argumentsAsAnonymousType"></param>
689 /// <returns></returns>
690 public virtual T Resolve
<T
>(String key
, object argumentsAsAnonymousType
)
692 return Resolve
<T
>(key
, new ReflectionBasedDictionaryAdapter(argumentsAsAnonymousType
));
696 /// Returns a component instance by the service
698 /// <typeparam name="T"></typeparam>
699 /// <returns></returns>
700 public T Resolve
<T
>()
702 return (T
) Resolve(typeof(T
));
706 /// Returns a component instance by the key
708 /// <param name="key"></param>
709 /// <returns></returns>
710 public virtual T Resolve
<T
>(String key
)
712 return (T
) Resolve(key
, typeof(T
));
716 /// Releases a component instance
718 /// <param name="instance"></param>
719 public virtual void Release(object instance
)
721 kernel
.ReleaseComponent(instance
);
725 /// Registers a subcontainer. The components exposed
726 /// by this container will be accessible from subcontainers.
728 /// <param name="childContainer"></param>
729 public virtual void AddChildContainer(IWindsorContainer childContainer
)
731 if (childContainer
== null) throw new ArgumentNullException("childContainer");
733 if (!childContainers
.Contains(childContainer
.Name
))
735 lock (childContainers
.SyncRoot
)
737 if (!childContainers
.Contains(childContainer
.Name
))
739 kernel
.AddChildKernel(childContainer
.Kernel
);
740 childContainers
.Add(childContainer
.Name
, childContainer
);
741 childContainer
.Parent
= this;
748 /// Removes (unregisters) a subcontainer. The components exposed by this container
749 /// will no longer be accessible to the child container.
751 /// <param name="childContainer"></param>
752 public virtual void RemoveChildContainer(IWindsorContainer childContainer
)
754 if (childContainer
== null) throw new ArgumentNullException("childContainer");
756 if (childContainers
.Contains(childContainer
.Name
))
758 lock (childContainers
.SyncRoot
)
760 if (childContainers
.Contains(childContainer
.Name
))
762 kernel
.RemoveChildKernel(childContainer
.Kernel
);
763 childContainers
.Remove(childContainer
.Name
);
764 childContainer
.Parent
= null;
771 /// Gets a child container instance by name.
773 /// <param name="name">The container's name.</param>
774 /// <returns>The child container instance or null</returns>
775 public IWindsorContainer
GetChildContainer(string name
)
777 return childContainers
[name
] as IWindsorContainer
;
782 #region IServiceProviderEx Members
785 /// Gets the service object of the specified type.
788 /// A service object of type serviceType.
790 /// <param name="serviceType">An object that specifies the type of service object to get. </param>
791 public object GetService(Type serviceType
)
793 return kernel
.GetService(serviceType
);
797 /// Gets the service object of the specified type.
800 /// A service object of type serviceType.
802 public T GetService
<T
>() where T
: class
804 return kernel
.GetService
<T
>();
809 #region IDisposable Members
812 /// Executes Dispose on underlying <see cref="IKernel"/>
814 public virtual void Dispose()
817 childContainers
.Clear();
823 #region Protected Operations Members
825 public IComponentsInstaller Installer
827 get { return installer; }
830 protected virtual void RunInstaller()
832 if (installer
!= null)
834 installer
.SetUp(this, kernel
.ConfigurationStore
);