using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Castle.DynamicProxy; using Castle.MicroKernel; using Castle.MicroKernel.Registration; using Castle.Windsor; using Castle.Windsor.Installer; using Castle.Windsor.Proxy; namespace Abp.Dependency { /// /// This class is used to directly perform dependency injection tasks. /// public class IocManager : IIocManager { /// /// The Singleton instance. /// public static IocManager Instance { get; private set; } /// /// Singletone instance for Castle ProxyGenerator. /// From Castle.Core documentation it is highly recomended to use single instance of ProxyGenerator to avoid memoryleaks and performance issues /// Follow next links for more details: /// Castle.Core documentation, /// Article /// private static readonly ProxyGenerator ProxyGeneratorInstance = new ProxyGenerator(); /// /// Reference to the Castle Windsor Container. /// public IWindsorContainer IocContainer { get; private set; } /// /// List of all registered conventional registrars. /// private readonly List _conventionalRegistrars; static IocManager() { Instance = new IocManager(); } /// /// Creates a new object. /// Normally, you don't directly instantiate an . /// This may be useful for test purposes. /// public IocManager() { IocContainer = CreateContainer(); _conventionalRegistrars = new List(); //Register self! IocContainer.Register( Component .For() .Instance(this) ); } protected virtual IWindsorContainer CreateContainer() { return new WindsorContainer(new DefaultProxyFactory(ProxyGeneratorInstance)); } /// /// Adds a dependency registrar for conventional registration. /// /// dependency registrar public void AddConventionalRegistrar(IConventionalDependencyRegistrar registrar) { _conventionalRegistrars.Add(registrar); } /// /// Registers types of given assembly by all conventional registrars. See method. /// /// Assembly to register public void RegisterAssemblyByConvention(Assembly assembly) { RegisterAssemblyByConvention(assembly, new ConventionalRegistrationConfig()); } /// /// Registers types of given assembly by all conventional registrars. See method. /// /// Assembly to register /// Additional configuration public void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config) { var context = new ConventionalRegistrationContext(assembly, this, config); foreach (var registerer in _conventionalRegistrars) { registerer.RegisterAssembly(context); } if (config.InstallInstallers) { IocContainer.Install(FromAssembly.Instance(assembly)); } } /// /// Registers a type as self registration. /// /// Type of the class /// Lifestyle of the objects of this type public void Register(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton) where TType : class { IocContainer.Register(ApplyLifestyle(Component.For(), lifeStyle)); } /// /// Registers a type as self registration. /// /// Type of the class /// Lifestyle of the objects of this type public void Register(Type type, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton) { IocContainer.Register(ApplyLifestyle(Component.For(type), lifeStyle)); } /// /// Registers a type with it's implementation. /// /// Registering type /// The type that implements /// Lifestyle of the objects of this type public void Register(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton) where TType : class where TImpl : class, TType { IocContainer.Register(ApplyLifestyle(Component.For().ImplementedBy(), lifeStyle)); } /// /// Registers a type with it's implementation. /// /// Type of the class /// The type that implements /// Lifestyle of the objects of this type public void Register(Type type, Type impl, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton) { IocContainer.Register(ApplyLifestyle(Component.For(type, impl).ImplementedBy(impl), lifeStyle)); } /// /// Checks whether given type is registered before. /// /// Type to check public bool IsRegistered(Type type) { return IocContainer.Kernel.HasComponent(type); } /// /// Checks whether given type is registered before. /// /// Type to check public bool IsRegistered() { return IocContainer.Kernel.HasComponent(typeof(TType)); } /// /// Gets an object from IOC container. /// Returning object must be Released (see ) after usage. /// /// Type of the object to get /// The instance object public T Resolve() { return IocContainer.Resolve(); } /// /// Gets an object from IOC container. /// Returning object must be Released (see ) after usage. /// /// Type of the object to cast /// Type of the object to resolve /// The object instance public T Resolve(Type type) { return (T)IocContainer.Resolve(type); } /// /// Gets an object from IOC container. /// Returning object must be Released (see ) after usage. /// /// Type of the object to get /// Constructor arguments /// The instance object public T Resolve(object argumentsAsAnonymousType) { return IocContainer.Resolve(argumentsAsAnonymousType); } /// /// Gets an object from IOC container. /// Returning object must be Released (see ) after usage. /// /// Type of the object to get /// The instance object public object Resolve(Type type) { return IocContainer.Resolve(type); } /// /// Gets an object from IOC container. /// Returning object must be Released (see ) after usage. /// /// Type of the object to get /// Constructor arguments /// The instance object public object Resolve(Type type, object argumentsAsAnonymousType) { return IocContainer.Resolve(type, argumentsAsAnonymousType); } /// public T[] ResolveAll() { return IocContainer.ResolveAll(); } /// public T[] ResolveAll(object argumentsAsAnonymousType) { return IocContainer.ResolveAll(argumentsAsAnonymousType); } /// public object[] ResolveAll(Type type) { return IocContainer.ResolveAll(type).Cast().ToArray(); } /// public object[] ResolveAll(Type type, object argumentsAsAnonymousType) { return IocContainer.ResolveAll(type, argumentsAsAnonymousType).Cast().ToArray(); } /// /// Releases a pre-resolved object. See Resolve methods. /// /// Object to be released public void Release(object obj) { IocContainer.Release(obj); } /// public void Dispose() { IocContainer.Dispose(); } private static ComponentRegistration ApplyLifestyle(ComponentRegistration registration, DependencyLifeStyle lifeStyle) where T : class { switch (lifeStyle) { case DependencyLifeStyle.Transient: return registration.LifestyleTransient(); case DependencyLifeStyle.Singleton: return registration.LifestyleSingleton(); default: return registration; } } } }