<PackageReference Include="Castle.Windsor" Version="3.4.0" />

BasedOnDescriptor

Describes how to register a group of related types.
using Castle.Core; using Castle.MicroKernel.Lifestyle.Scoped; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; namespace Castle.MicroKernel.Registration { public class BasedOnDescriptor : IRegistration { private readonly List<Type> potentialBases; private Action<ComponentRegistration> configuration; private readonly FromDescriptor from; private readonly ServiceDescriptor service; private Predicate<Type> ifFilter; private Predicate<Type> unlessFilter; public ServiceDescriptor WithService => service; internal BasedOnDescriptor(IEnumerable<Type> basedOn, FromDescriptor from, Predicate<Type> additionalFilters) { potentialBases = basedOn.ToList(); this.from = from; service = new ServiceDescriptor(this); If(additionalFilters); } public FromDescriptor AllowMultipleMatches() { return from.AllowMultipleMatches(); } [Obsolete("Calling this method resets registration. If that's what you want, start anew, with Classes.FromAssembly..")] [EditorBrowsable(EditorBrowsableState.Never)] public BasedOnDescriptor BasedOn<T>() { return from.BasedOn<T>(); } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Calling this method resets registration. If that's what you want, start anew, with Classes.FromAssembly...")] public BasedOnDescriptor BasedOn(Type basedOn) { return from.BasedOn(basedOn); } public BasedOnDescriptor OrBasedOn(Type basedOn) { potentialBases.Add(basedOn); return this; } public BasedOnDescriptor Configure(Action<ComponentRegistration> configurer) { configuration = (Action<ComponentRegistration>)Delegate.Combine(configuration, configurer); return this; } public BasedOnDescriptor ConfigureFor<TComponentImplementationType>(Action<ComponentRegistration> configurer) { return ConfigureIf((ComponentRegistration r) => typeof(TComponentImplementationType).IsAssignableFrom(((ComponentRegistration<object>)r).Implementation), configurer); } public BasedOnDescriptor ConfigureIf(Predicate<ComponentRegistration> condition, Action<ComponentRegistration> configurer) { configuration = (Action<ComponentRegistration>)Delegate.Combine(configuration, (Action<ComponentRegistration>)delegate(ComponentRegistration r) { if (condition(r)) configurer(r); }); return this; } public BasedOnDescriptor ConfigureIf(Predicate<ComponentRegistration> condition, Action<ComponentRegistration> configurerWhenTrue, Action<ComponentRegistration> configurerWhenFalse) { configuration = (Action<ComponentRegistration>)Delegate.Combine(configuration, (Action<ComponentRegistration>)delegate(ComponentRegistration r) { if (condition(r)) configurerWhenTrue(r); else configurerWhenFalse(r); }); return this; } public BasedOnDescriptor If(Predicate<Type> ifFilter) { this.ifFilter = (Predicate<Type>)Delegate.Combine(this.ifFilter, ifFilter); return this; } public BasedOnDescriptor Unless(Predicate<Type> unlessFilter) { this.unlessFilter = (Predicate<Type>)Delegate.Combine(this.unlessFilter, unlessFilter); return this; } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Calling this method resets registration. If that's what you want, start anew, with Classes.FromAssembly...")] public BasedOnDescriptor Where(Predicate<Type> accepted) { return from.Where(accepted); } public BasedOnDescriptor WithServiceAllInterfaces() { return WithService.AllInterfaces(); } public BasedOnDescriptor WithServiceBase() { return WithService.Base(); } public BasedOnDescriptor WithServiceDefaultInterfaces() { return WithService.DefaultInterfaces(); } public BasedOnDescriptor WithServiceFirstInterface() { return WithService.FirstInterface(); } public BasedOnDescriptor WithServiceFromInterface(Type implements) { return WithService.FromInterface(implements); } public BasedOnDescriptor WithServiceFromInterface() { return WithService.FromInterface(); } public BasedOnDescriptor WithServiceSelect(ServiceDescriptor.ServiceSelector selector) { return WithService.Select(selector); } public BasedOnDescriptor WithServiceSelf() { return WithService.Self(); } public BasedOnDescriptor LifestyleCustom(Type customLifestyleType) { return Configure(delegate(ComponentRegistration c) { c.LifestyleCustom(customLifestyleType); }); } public BasedOnDescriptor LifestyleCustom<TLifestyleManager>() where TLifestyleManager : ILifestyleManager, new { return Configure(delegate(ComponentRegistration c) { c.LifestyleCustom<TLifestyleManager>(); }); } public BasedOnDescriptor LifestylePerThread() { return Configure(delegate(ComponentRegistration c) { c.LifestylePerThread(); }); } public BasedOnDescriptor LifestyleScoped() { return Configure(delegate(ComponentRegistration c) { c.LifestyleScoped(null); }); } public BasedOnDescriptor LifestyleScoped(Type scopeAccessorType) { return Configure(delegate(ComponentRegistration c) { c.LifestyleScoped(scopeAccessorType); }); } public BasedOnDescriptor LifestyleScoped<TScopeAccessor>() where TScopeAccessor : IScopeAccessor, new { return Configure(delegate(ComponentRegistration c) { c.LifestyleScoped<TScopeAccessor>(); }); } public BasedOnDescriptor LifestyleBoundTo<TBaseForRoot>() where TBaseForRoot : class { return Configure(delegate(ComponentRegistration c) { c.LifestyleBoundTo<TBaseForRoot>(); }); } public BasedOnDescriptor LifestyleBoundToNearest<TBaseForRoot>() where TBaseForRoot : class { return Configure(delegate(ComponentRegistration c) { c.LifestyleBoundToNearest<TBaseForRoot>(); }); } public BasedOnDescriptor LifestylePerWebRequest() { return Configure(delegate(ComponentRegistration c) { c.LifestylePerWebRequest(); }); } public BasedOnDescriptor LifestylePooled(int? initialSize = default(int?), int? maxSize = default(int?)) { return Configure(delegate(ComponentRegistration c) { c.LifestylePooled(initialSize, maxSize); }); } public BasedOnDescriptor LifestyleSingleton() { return Configure(delegate(ComponentRegistration c) { c.LifestyleSingleton(); }); } public BasedOnDescriptor LifestyleTransient() { return Configure(delegate(ComponentRegistration c) { c.LifestyleTransient(); }); } public BasedOnDescriptor WithServices(IEnumerable<Type> types) { return WithService.Select(types); } public BasedOnDescriptor WithServices(params Type[] types) { return WithService.Select(types); } protected virtual bool Accepts(Type type, out Type[] baseTypes) { if (IsBasedOn(type, out baseTypes) && ExecuteIfCondition(type)) return !ExecuteUnlessCondition(type); return false; } protected bool ExecuteIfCondition(Type type) { if (ifFilter == null) return true; Delegate[] invocationList = ifFilter.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Predicate<Type> predicate = (Predicate<Type>)invocationList[i]; if (!predicate(type)) return false; } return true; } protected bool ExecuteUnlessCondition(Type type) { if (unlessFilter == null) return false; Delegate[] invocationList = unlessFilter.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Predicate<Type> predicate = (Predicate<Type>)invocationList[i]; if (predicate(type)) return true; } return false; } protected bool IsBasedOn(Type type, out Type[] baseTypes) { List<Type> list = new List<Type>(); foreach (Type potentialBasis in potentialBases) { if (potentialBasis.IsAssignableFrom(type)) list.Add(potentialBasis); else if (potentialBasis.IsGenericTypeDefinition) { if (potentialBasis.IsInterface && IsBasedOnGenericInterface(type, potentialBasis, out baseTypes)) list.AddRange(baseTypes); if (IsBasedOnGenericClass(type, potentialBasis, out baseTypes)) list.AddRange(baseTypes); } } baseTypes = list.Distinct().ToArray(); return baseTypes.Length > 0; } internal bool TryRegister(Type type, IKernel kernel) { if (!Accepts(type, out Type[] baseTypes)) return false; CastleComponentAttribute defaultsFor = CastleComponentAttribute.GetDefaultsFor(type); ICollection<Type> services = service.GetServices(type, baseTypes); if (services.Count == 0 && defaultsFor.Services.Length > 0) services = defaultsFor.Services; ComponentRegistration componentRegistration = Component.For(services); componentRegistration.ImplementedBy(type); if (configuration != null) configuration(componentRegistration); if (string.IsNullOrEmpty(componentRegistration.Name) && !string.IsNullOrEmpty(defaultsFor.Name)) componentRegistration.Named(defaultsFor.Name); else componentRegistration.RegisterOptionally(); kernel.Register(componentRegistration); return true; } private static bool IsBasedOnGenericClass(Type type, Type basedOn, out Type[] baseTypes) { while (type != (Type)null) { if (type.IsGenericType && type.GetGenericTypeDefinition() == basedOn) { baseTypes = new Type[1] { type }; return true; } type = type.BaseType; } baseTypes = null; return false; } private static bool IsBasedOnGenericInterface(Type type, Type basedOn, out Type[] baseTypes) { List<Type> list = new List<Type>(4); Type[] interfaces = type.GetInterfaces(); foreach (Type type2 in interfaces) { if (type2.IsGenericType && type2.GetGenericTypeDefinition() == basedOn) { if (type2.ReflectedType == (Type)null && type2.ContainsGenericParameters) list.Add(type2.GetGenericTypeDefinition()); else list.Add(type2); } } baseTypes = list.ToArray(); return baseTypes.Length > 0; } void IRegistration.Register(IKernelInternal kernel) { ((IRegistration)from).Register(kernel); } } }