IocManager.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using Castle.DynamicProxy;
  6. using Castle.MicroKernel;
  7. using Castle.MicroKernel.Registration;
  8. using Castle.Windsor;
  9. using Castle.Windsor.Installer;
  10. using Castle.Windsor.Proxy;
  11. namespace Abp.Dependency
  12. {
  13. /// <summary>
  14. /// This class is used to directly perform dependency injection tasks.
  15. /// </summary>
  16. public class IocManager : IIocManager
  17. {
  18. /// <summary>
  19. /// The Singleton instance.
  20. /// </summary>
  21. public static IocManager Instance { get; private set; }
  22. /// <summary>
  23. /// Singletone instance for Castle ProxyGenerator.
  24. /// From Castle.Core documentation it is highly recomended to use single instance of ProxyGenerator to avoid memoryleaks and performance issues
  25. /// Follow next links for more details:
  26. /// <a href="https://github.com/castleproject/Core/blob/master/docs/dynamicproxy.md">Castle.Core documentation</a>,
  27. /// <a href="http://kozmic.net/2009/07/05/castle-dynamic-proxy-tutorial-part-xii-caching/">Article</a>
  28. /// </summary>
  29. private static readonly ProxyGenerator ProxyGeneratorInstance = new ProxyGenerator();
  30. /// <summary>
  31. /// Reference to the Castle Windsor Container.
  32. /// </summary>
  33. public IWindsorContainer IocContainer { get; private set; }
  34. /// <summary>
  35. /// List of all registered conventional registrars.
  36. /// </summary>
  37. private readonly List<IConventionalDependencyRegistrar> _conventionalRegistrars;
  38. static IocManager()
  39. {
  40. Instance = new IocManager();
  41. }
  42. /// <summary>
  43. /// Creates a new <see cref="IocManager"/> object.
  44. /// Normally, you don't directly instantiate an <see cref="IocManager"/>.
  45. /// This may be useful for test purposes.
  46. /// </summary>
  47. public IocManager()
  48. {
  49. IocContainer = CreateContainer();
  50. _conventionalRegistrars = new List<IConventionalDependencyRegistrar>();
  51. //Register self!
  52. IocContainer.Register(
  53. Component
  54. .For<IocManager, IIocManager, IIocRegistrar, IIocResolver>()
  55. .Instance(this)
  56. );
  57. }
  58. protected virtual IWindsorContainer CreateContainer()
  59. {
  60. return new WindsorContainer(new DefaultProxyFactory(ProxyGeneratorInstance));
  61. }
  62. /// <summary>
  63. /// Adds a dependency registrar for conventional registration.
  64. /// </summary>
  65. /// <param name="registrar">dependency registrar</param>
  66. public void AddConventionalRegistrar(IConventionalDependencyRegistrar registrar)
  67. {
  68. _conventionalRegistrars.Add(registrar);
  69. }
  70. /// <summary>
  71. /// Registers types of given assembly by all conventional registrars. See <see cref="AddConventionalRegistrar"/> method.
  72. /// </summary>
  73. /// <param name="assembly">Assembly to register</param>
  74. public void RegisterAssemblyByConvention(Assembly assembly)
  75. {
  76. RegisterAssemblyByConvention(assembly, new ConventionalRegistrationConfig());
  77. }
  78. /// <summary>
  79. /// Registers types of given assembly by all conventional registrars. See <see cref="AddConventionalRegistrar"/> method.
  80. /// </summary>
  81. /// <param name="assembly">Assembly to register</param>
  82. /// <param name="config">Additional configuration</param>
  83. public void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config)
  84. {
  85. var context = new ConventionalRegistrationContext(assembly, this, config);
  86. foreach (var registerer in _conventionalRegistrars)
  87. {
  88. registerer.RegisterAssembly(context);
  89. }
  90. if (config.InstallInstallers)
  91. {
  92. IocContainer.Install(FromAssembly.Instance(assembly));
  93. }
  94. }
  95. /// <summary>
  96. /// Registers a type as self registration.
  97. /// </summary>
  98. /// <typeparam name="TType">Type of the class</typeparam>
  99. /// <param name="lifeStyle">Lifestyle of the objects of this type</param>
  100. public void Register<TType>(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton) where TType : class
  101. {
  102. IocContainer.Register(ApplyLifestyle(Component.For<TType>(), lifeStyle));
  103. }
  104. /// <summary>
  105. /// Registers a type as self registration.
  106. /// </summary>
  107. /// <param name="type">Type of the class</param>
  108. /// <param name="lifeStyle">Lifestyle of the objects of this type</param>
  109. public void Register(Type type, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
  110. {
  111. IocContainer.Register(ApplyLifestyle(Component.For(type), lifeStyle));
  112. }
  113. /// <summary>
  114. /// Registers a type with it's implementation.
  115. /// </summary>
  116. /// <typeparam name="TType">Registering type</typeparam>
  117. /// <typeparam name="TImpl">The type that implements <see cref="TType"/></typeparam>
  118. /// <param name="lifeStyle">Lifestyle of the objects of this type</param>
  119. public void Register<TType, TImpl>(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
  120. where TType : class
  121. where TImpl : class, TType
  122. {
  123. IocContainer.Register(ApplyLifestyle(Component.For<TType, TImpl>().ImplementedBy<TImpl>(), lifeStyle));
  124. }
  125. /// <summary>
  126. /// Registers a type with it's implementation.
  127. /// </summary>
  128. /// <param name="type">Type of the class</param>
  129. /// <param name="impl">The type that implements <paramref name="type"/></param>
  130. /// <param name="lifeStyle">Lifestyle of the objects of this type</param>
  131. public void Register(Type type, Type impl, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
  132. {
  133. IocContainer.Register(ApplyLifestyle(Component.For(type, impl).ImplementedBy(impl), lifeStyle));
  134. }
  135. /// <summary>
  136. /// Checks whether given type is registered before.
  137. /// </summary>
  138. /// <param name="type">Type to check</param>
  139. public bool IsRegistered(Type type)
  140. {
  141. return IocContainer.Kernel.HasComponent(type);
  142. }
  143. /// <summary>
  144. /// Checks whether given type is registered before.
  145. /// </summary>
  146. /// <typeparam name="TType">Type to check</typeparam>
  147. public bool IsRegistered<TType>()
  148. {
  149. return IocContainer.Kernel.HasComponent(typeof(TType));
  150. }
  151. /// <summary>
  152. /// Gets an object from IOC container.
  153. /// Returning object must be Released (see <see cref="IIocResolver.Release"/>) after usage.
  154. /// </summary>
  155. /// <typeparam name="T">Type of the object to get</typeparam>
  156. /// <returns>The instance object</returns>
  157. public T Resolve<T>()
  158. {
  159. return IocContainer.Resolve<T>();
  160. }
  161. /// <summary>
  162. /// Gets an object from IOC container.
  163. /// Returning object must be Released (see <see cref="Release"/>) after usage.
  164. /// </summary>
  165. /// <typeparam name="T">Type of the object to cast</typeparam>
  166. /// <param name="type">Type of the object to resolve</param>
  167. /// <returns>The object instance</returns>
  168. public T Resolve<T>(Type type)
  169. {
  170. return (T)IocContainer.Resolve(type);
  171. }
  172. /// <summary>
  173. /// Gets an object from IOC container.
  174. /// Returning object must be Released (see <see cref="IIocResolver.Release"/>) after usage.
  175. /// </summary>
  176. /// <typeparam name="T">Type of the object to get</typeparam>
  177. /// <param name="argumentsAsAnonymousType">Constructor arguments</param>
  178. /// <returns>The instance object</returns>
  179. public T Resolve<T>(object argumentsAsAnonymousType)
  180. {
  181. return IocContainer.Resolve<T>(argumentsAsAnonymousType);
  182. }
  183. /// <summary>
  184. /// Gets an object from IOC container.
  185. /// Returning object must be Released (see <see cref="IIocResolver.Release"/>) after usage.
  186. /// </summary>
  187. /// <param name="type">Type of the object to get</param>
  188. /// <returns>The instance object</returns>
  189. public object Resolve(Type type)
  190. {
  191. return IocContainer.Resolve(type);
  192. }
  193. /// <summary>
  194. /// Gets an object from IOC container.
  195. /// Returning object must be Released (see <see cref="IIocResolver.Release"/>) after usage.
  196. /// </summary>
  197. /// <param name="type">Type of the object to get</param>
  198. /// <param name="argumentsAsAnonymousType">Constructor arguments</param>
  199. /// <returns>The instance object</returns>
  200. public object Resolve(Type type, object argumentsAsAnonymousType)
  201. {
  202. return IocContainer.Resolve(type, argumentsAsAnonymousType);
  203. }
  204. ///<inheritdoc/>
  205. public T[] ResolveAll<T>()
  206. {
  207. return IocContainer.ResolveAll<T>();
  208. }
  209. ///<inheritdoc/>
  210. public T[] ResolveAll<T>(object argumentsAsAnonymousType)
  211. {
  212. return IocContainer.ResolveAll<T>(argumentsAsAnonymousType);
  213. }
  214. ///<inheritdoc/>
  215. public object[] ResolveAll(Type type)
  216. {
  217. return IocContainer.ResolveAll(type).Cast<object>().ToArray();
  218. }
  219. ///<inheritdoc/>
  220. public object[] ResolveAll(Type type, object argumentsAsAnonymousType)
  221. {
  222. return IocContainer.ResolveAll(type, argumentsAsAnonymousType).Cast<object>().ToArray();
  223. }
  224. /// <summary>
  225. /// Releases a pre-resolved object. See Resolve methods.
  226. /// </summary>
  227. /// <param name="obj">Object to be released</param>
  228. public void Release(object obj)
  229. {
  230. IocContainer.Release(obj);
  231. }
  232. /// <inheritdoc/>
  233. public void Dispose()
  234. {
  235. IocContainer.Dispose();
  236. }
  237. private static ComponentRegistration<T> ApplyLifestyle<T>(ComponentRegistration<T> registration, DependencyLifeStyle lifeStyle)
  238. where T : class
  239. {
  240. switch (lifeStyle)
  241. {
  242. case DependencyLifeStyle.Transient:
  243. return registration.LifestyleTransient();
  244. case DependencyLifeStyle.Singleton:
  245. return registration.LifestyleSingleton();
  246. default:
  247. return registration;
  248. }
  249. }
  250. }
  251. }