/// <summary> /// Cleanups up injectable properties. All injectable properties will be set to <c>null</c>. /// </summary> /// <remarks> /// Since this method does not perform dependency validation /// <see cref="InjectProperties" /> , <paramref name="cache" /> is used as read-only. /// Calling <see cref="CleanupInjectableProperties" /> without call to <see cref="InjectProperties" /> on the same type /// will incur performance penalty as list of properties will be evaluated every time. /// </remarks> /// <param name="kernel">Windsor kernel.</param> /// <param name="target">The target object to cleanup injectable properties.</param> /// <param name="cache">Injectable property descriptor cache.</param> public static void CleanupInjectableProperties([NotNull] this IKernel kernel, [NotNull] object target, ITypePropertyDescriptorCache cache) { if (kernel == null) { throw new ArgumentNullException(nameof(kernel)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } Type type = target.GetType(); // Cache miss expected only once per given type, so call Find() first to prevent extra closure allocation in GetOrAdd. TypePropertyDescriptor info = cache?.Find(type) ?? GetInjectableProperties(type, kernel, null); if (!info.HasProperties()) { return; } // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < info.Properties.Length; i++) { info.Properties[i].SetValue(target, null, null); } }
/// <summary> /// Configures Web API runtime to use Castle Windsor Container /// </summary> /// <param name="configuration">Configuration</param> /// <param name="container">Windsor container to use</param> /// <param name="injectablePropertyCache">Injectable property cache</param> /// <remarks> /// Performs following actions /// <list type="bullet"> /// <item> /// <description>Install DependencyResolver <see cref="IDependencyResolver" /></description> /// </item> /// <item> /// <description> /// Add property injection support for ActionFilters, <see cref="WindsorHttpFilterProvider" /> /// </description> /// </item> /// </list> /// </remarks> /// <returns> /// <see cref="HttpConfiguration" /> /// </returns> public static HttpConfiguration UseWindsor(this HttpConfiguration configuration, IWindsorContainer container, ITypePropertyDescriptorCache injectablePropertyCache) { configuration.DependencyResolver = new WindsorDependencyResolver(container); configuration.Services.InstallHttpFilterProvider(container, injectablePropertyCache); return(configuration); }
/// <summary> /// Configures Web API runtime to use Castle Windsor Container /// </summary> /// <param name="configuration">Configuration</param> /// <param name="container">Windsor container to use</param> /// <param name="injectablePropertyCache">Injectable property cache</param> /// <remarks> /// Performs following actions /// <list type="bullet"> /// <item> /// <description>Install DependencyResolver <see cref="IDependencyResolver" /></description> /// </item> /// <item> /// <description> /// Add property injection support for ActionFilters, <see cref="WindsorHttpFilterProvider" /> /// </description> /// </item> /// </list> /// </remarks> /// <returns> /// <see cref="HttpConfiguration" /> /// </returns> public static HttpConfiguration UseWindsor(this HttpConfiguration configuration, IWindsorContainer container, ITypePropertyDescriptorCache injectablePropertyCache) { configuration.DependencyResolver = new WindsorDependencyResolver(container); configuration.Services.InstallHttpFilterProvider(container, injectablePropertyCache); return configuration; }
/// <summary> /// Create new instance. /// </summary> /// <param name="container">Windsor container.</param> /// <param name="typePropertyDescriptorCache"></param> /// <exception cref="ArgumentNullException">Container is <c>null</c>.</exception> public WindsorFilterAttributeProvider([NotNull] IWindsorContainer container, [CanBeNull] ITypePropertyDescriptorCache typePropertyDescriptorCache) : base(false) { if (container == null) throw new ArgumentNullException(nameof(container)); this.container = container; this.typePropertyDescriptorCache = typePropertyDescriptorCache; }
/// <summary> /// Create new instance. /// </summary> /// <param name="container">Windsor container.</param> /// <param name="typePropertyDescriptorCache"></param> /// <exception cref="ArgumentNullException">Container is <c>null</c>.</exception> public WindsorFilterAttributeProvider([NotNull] IWindsorContainer container, [CanBeNull] ITypePropertyDescriptorCache typePropertyDescriptorCache) : base(false) { if (container == null) { throw new ArgumentNullException(nameof(container)); } this.container = container; this.typePropertyDescriptorCache = typePropertyDescriptorCache; }
/// <summary> /// Initializes a new instance of the <see cref="WindsorHttpFilterProvider" /> class. /// </summary> /// <param name="container">The container.</param> /// <param name="typePropertyDescriptorCache">Property descriptor cache.</param> public WindsorHttpFilterProvider([NotNull] IWindsorContainer container, [NotNull] ITypePropertyDescriptorCache typePropertyDescriptorCache) { if (container == null) throw new ArgumentNullException(nameof(container)); if (typePropertyDescriptorCache == null) throw new ArgumentNullException(nameof(typePropertyDescriptorCache)); this.container = container; this.typePropertyDescriptorCache = typePropertyDescriptorCache; }
/// <summary> /// Installs Filter provider with injectable property dependencies support. /// </summary> /// <param name="services">Services container, <see cref="ServicesContainer" /></param> /// <param name="container">Windsor container, <see cref="IWindsorContainer" /> </param> /// <param name="propertyDescriptorCache">Injectable property cache</param> /// <returns>Windsor container</returns> public static void InstallHttpFilterProvider([NotNull] this ServicesContainer services, [NotNull] IWindsorContainer container, ITypePropertyDescriptorCache propertyDescriptorCache) { if (services == null) throw new ArgumentNullException(nameof(services)); if (container == null) throw new ArgumentNullException(nameof(container)); var providers = services.GetFilterProviders().Where(i => i is ActionDescriptorFilterProvider).ToArray(); foreach (var filterProvider in providers) { services.Remove(typeof (IFilterProvider), filterProvider); } services.Add(typeof (IFilterProvider), new WindsorHttpFilterProvider(container, propertyDescriptorCache)); }
/// <summary> /// Initializes a new instance of the <see cref="WindsorHttpFilterProvider" /> class. /// </summary> /// <param name="container">The container.</param> /// <param name="typePropertyDescriptorCache">Property descriptor cache.</param> public WindsorHttpFilterProvider([NotNull] IWindsorContainer container, [NotNull] ITypePropertyDescriptorCache typePropertyDescriptorCache) { if (container == null) { throw new ArgumentNullException(nameof(container)); } if (typePropertyDescriptorCache == null) { throw new ArgumentNullException(nameof(typePropertyDescriptorCache)); } this.container = container; this.typePropertyDescriptorCache = typePropertyDescriptorCache; }
/// <summary> /// Cleanups up injectable properties. All injectable properties will be set to <c>null</c>. /// </summary> /// <remarks> /// Since this method does not perform dependency validation /// <see cref="InjectProperties" /> , <paramref name="cache" /> is used as read-only. /// Calling <see cref="CleanupInjectableProperties" /> without call to <see cref="InjectProperties" /> on the same type /// will incur performance penalty as list of properties will be evaluated every time. /// </remarks> /// <param name="kernel">Windsor kernel.</param> /// <param name="target">The target object to cleanup injectable properties.</param> /// <param name="cache">Injectable property descriptor cache.</param> public static void CleanupInjectableProperties([NotNull] this IKernel kernel, [NotNull] object target, ITypePropertyDescriptorCache cache) { if (kernel == null) throw new ArgumentNullException(nameof(kernel)); if (target == null) throw new ArgumentNullException(nameof(target)); Type type = target.GetType(); // Cache miss expected only once per given type, so call Find() first to prevent extra closure allocation in GetOrAdd. TypePropertyDescriptor info = cache?.Find(type) ?? GetInjectableProperties(type, kernel, null); if (!info.HasProperties()) return; // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < info.Properties.Length; i++) { info.Properties[i].SetValue(target, null, null); } }
/// <summary> /// Injects dependencies into properties. /// </summary> /// <param name="kernel">Windsor kernel</param> /// <param name="target">The target object to inject properties.</param> /// <param name="cache">Injectable property descriptor cache.</param> /// <param name="validatePropertyRegistration"> /// Callback to validate property dependency to be injected. Must throw /// exception in case of failure. /// </param> /// <exception cref="ComponentActivatorException"></exception> /// <exception cref="ArgumentNullException"><paramref name="target" /> is <see langword="null" />.</exception> public static void InjectProperties([NotNull] this IKernel kernel, [NotNull] object target, [CanBeNull] ITypePropertyDescriptorCache cache, Action <PropertyInfo, ComponentModel> validatePropertyRegistration = null) { if (kernel == null) { throw new ArgumentNullException(nameof(kernel)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } Type type = target.GetType(); TypePropertyDescriptor info = GetInjectableProperties(kernel, cache, validatePropertyRegistration, type); if (!info.HasProperties()) { return; } // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < info.Properties.Length; i++) { PropertyInfo injectableProperty = info.Properties[i]; object val = kernel.Resolve(injectableProperty.PropertyType); try { injectableProperty.SetValue(target, val, null); } catch (Exception ex) { string message = $"Error injecting property {injectableProperty.Name} on type {type.FullName}, See inner exception for more information."; throw new ComponentActivatorException(message, ex, null); } } }
private static TypePropertyDescriptor GetOrAdd(IKernel kernel, ITypePropertyDescriptorCache cache, Type type, Action<PropertyInfo, ComponentModel> validatePropertyRegistration) { return cache.GetOrAdd(type, t => GetInjectableProperties(t, kernel, validatePropertyRegistration)); }
private static TypePropertyDescriptor GetInjectableProperties(IKernel kernel, ITypePropertyDescriptorCache cache, Action<PropertyInfo, ComponentModel> validatePropertyRegistration, Type type) { // Cache miss expected only once per given type, so call Find() first to prevent extra closure allocation in GetOrAdd. TypePropertyDescriptor info = cache != null ? cache.Find(type) ?? GetOrAdd(kernel, cache, type, validatePropertyRegistration) : GetInjectableProperties(type, kernel, validatePropertyRegistration); return info; }
/// <summary> /// Installs Filter provider with injectable property dependencies support. /// </summary> /// <param name="services">Services container, <see cref="ServicesContainer" /></param> /// <param name="container">Windsor container, <see cref="IWindsorContainer" /> </param> /// <param name="propertyDescriptorCache">Injectable property cache</param> /// <returns>Windsor container</returns> public static void InstallHttpFilterProvider([NotNull] this ServicesContainer services, [NotNull] IWindsorContainer container, ITypePropertyDescriptorCache propertyDescriptorCache) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (container == null) { throw new ArgumentNullException(nameof(container)); } var providers = services.GetFilterProviders().Where(i => i is ActionDescriptorFilterProvider).ToArray(); foreach (var filterProvider in providers) { services.Remove(typeof(IFilterProvider), filterProvider); } services.Add(typeof(IFilterProvider), new WindsorHttpFilterProvider(container, propertyDescriptorCache)); }
private static TypePropertyDescriptor GetOrAdd(IKernel kernel, ITypePropertyDescriptorCache cache, Type type, Action <PropertyInfo, ComponentModel> validatePropertyRegistration) { return(cache.GetOrAdd(type, t => GetInjectableProperties(t, kernel, validatePropertyRegistration))); }
private static TypePropertyDescriptor GetInjectableProperties(IKernel kernel, ITypePropertyDescriptorCache cache, Action <PropertyInfo, ComponentModel> validatePropertyRegistration, Type type) { // Cache miss expected only once per given type, so call Find() first to prevent extra closure allocation in GetOrAdd. TypePropertyDescriptor info = cache != null ? cache.Find(type) ?? GetOrAdd(kernel, cache, type, validatePropertyRegistration) : GetInjectableProperties(type, kernel, validatePropertyRegistration); return(info); }