<PackageReference Include="Castle.Windsor" Version="5.0.0-beta001" />

DefaultKernel

Default implementation of IKernel. This implementation is complete and also support a kernel hierarchy (sub containers).
using Castle.Core; using Castle.Core.Internal; using Castle.Core.Logging; using Castle.MicroKernel.ComponentActivator; using Castle.MicroKernel.Context; using Castle.MicroKernel.Handlers; using Castle.MicroKernel.Lifestyle; using Castle.MicroKernel.Lifestyle.Scoped; using Castle.MicroKernel.ModelBuilder; using Castle.MicroKernel.ModelBuilder.Inspectors; using Castle.MicroKernel.Proxy; using Castle.MicroKernel.Registration; using Castle.MicroKernel.Releasers; using Castle.MicroKernel.Resolvers; using Castle.MicroKernel.SubSystems.Configuration; using Castle.MicroKernel.SubSystems.Conversion; using Castle.MicroKernel.SubSystems.Naming; using Castle.MicroKernel.SubSystems.Resource; using Castle.Windsor.Diagnostics; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; namespace Castle.MicroKernel { [Serializable] [DebuggerTypeProxy(typeof(KernelDebuggerProxy))] public class DefaultKernel : IKernel, IKernelEvents, IDisposable, IKernelInternal { private class OptimizeDependencyResolutionDisposable : IDisposable { private readonly DefaultKernel kernel; public OptimizeDependencyResolutionDisposable(DefaultKernel kernel) { this.kernel = kernel; } public void Dispose() { lock (kernel.handlersChangedLock) { try { if (kernel.handlersChanged) { kernel.DoActualRaisingOfHandlersChanged(); kernel.RaiseRegistrationCompleted(); kernel.handlersChanged = false; } } finally { kernel.handlersChangedDeferred = false; } } } } [ThreadStatic] private static CreationContext currentCreationContext; [ThreadStatic] private static bool isCheckingLazyLoaders; private ThreadSafeFlag disposed; private readonly List<IKernel> childKernels = new List<IKernel>(); private readonly List<IFacility> facilities = new List<IFacility>(); private readonly Dictionary<string, ISubSystem> subsystems = new Dictionary<string, ISubSystem>(StringComparer.OrdinalIgnoreCase); private IKernel parentKernel; private readonly object lazyLoadingLock = new object(); private readonly object handlersChangedLock = new object(); private bool handlersChanged; private volatile bool handlersChangedDeferred; public IComponentModelBuilder ComponentModelBuilder { get; set; } public virtual IConfigurationStore ConfigurationStore { get { return GetSubSystem(SubSystemConstants.ConfigurationStoreKey) as IConfigurationStore; } set { AddSubSystem(SubSystemConstants.ConfigurationStoreKey, value); } } public GraphNode[] GraphNodes { get { GraphNode[] array = new GraphNode[NamingSubSystem.ComponentCount]; int num = 0; IHandler[] allHandlers = NamingSubSystem.GetAllHandlers(); foreach (IHandler handler in allHandlers) { array[num++] = handler.ComponentModel; } return array; } } public IHandlerFactory HandlerFactory { get; set; } public virtual IKernel Parent { get { return parentKernel; } set { if (value == null) { if (parentKernel != null) { UnsubscribeFromParentKernel(); RaiseRemovedAsChildKernel(); } parentKernel = null; } else { if (parentKernel != value && parentKernel != null) throw new KernelException("You can not change the kernel parent once set, use the RemoveChildKernel and AddChildKernel methods together to achieve this."); parentKernel = value; SubscribeToParentKernel(); RaiseAddedAsChildKernel(); } } } public IProxyFactory ProxyFactory { get; set; } public IReleasePolicy ReleasePolicy { get; set; } public IDependencyResolver Resolver { get; set; } protected IConversionManager ConversionSubSystem { get; set; } protected INamingSubSystem NamingSubSystem { get; set; } public ILogger Logger { get; set; } public event HandlerDelegate HandlerRegistered = delegate { }; public event HandlersChangedDelegate HandlersChanged = delegate { }; public event ComponentDataDelegate ComponentRegistered = delegate { }; public event ComponentInstanceDelegate ComponentCreated = delegate { }; public event ComponentInstanceDelegate ComponentDestroyed = delegate { }; public event EventHandler AddedAsChildKernel = delegate { }; public event EventHandler RegistrationCompleted = delegate { }; public event EventHandler RemovedAsChildKernel = delegate { }; public event ComponentModelDelegate ComponentModelCreated = delegate { }; public event DependencyDelegate DependencyResolving = delegate { }; public event ServiceDelegate EmptyCollectionResolving = delegate { }; public DefaultKernel() : this(new NotSupportedProxyFactory()) { } public DefaultKernel(IDependencyResolver resolver, IProxyFactory proxyFactory) { RegisterSubSystems(); ReleasePolicy = new LifecycledComponentsReleasePolicy(this); HandlerFactory = new DefaultHandlerFactory(this); ComponentModelBuilder = new DefaultComponentModelBuilder(this); ProxyFactory = proxyFactory; Resolver = resolver; Resolver.Initialize(this, RaiseDependencyResolving); Logger = NullLogger.Instance; } public DefaultKernel(IProxyFactory proxyFactory) : this(new DefaultDependencyResolver(), proxyFactory) { } public virtual void Dispose() { if (disposed.Signal()) { DisposeSubKernels(); TerminateFacilities(); DisposeHandlers(); DisposeComponentsInstancesWithinTracker(); UnsubscribeFromParentKernel(); } } public virtual void AddChildKernel(IKernel childKernel) { if (childKernel == null) throw new ArgumentNullException("childKernel"); childKernel.Parent = this; childKernels.Add(childKernel); } public virtual IHandler AddCustomComponent(ComponentModel model) { IHandler handler = ((IKernelInternal)this).CreateHandler(model); NamingSubSystem.Register(handler); ((IKernelInternal)this).RaiseEventsOnHandlerCreated(handler); return handler; } IHandler IKernelInternal.CreateHandler(ComponentModel model) { if (model == null) throw new ArgumentNullException("model"); RaiseComponentModelCreated(model); return HandlerFactory.Create(model); } public virtual IKernel AddFacility(IFacility facility) { if (facility == null) throw new ArgumentNullException("facility"); Type facilityType = facility.GetType(); if (facilities.Any((IFacility f) => (object)f.GetType() == facilityType)) throw new ArgumentException($"""{facilityType.FullName}"""); facilities.Add(facility); facility.Init(this, ConfigurationStore.GetFacilityConfiguration(facility.GetType().FullName)); return this; } public IKernel AddFacility<T>() where T : IFacility, new { return AddFacility((IFacility)(object)new T()); } public IKernel AddFacility<T>(Action<T> onCreate) where T : IFacility, new { T val = new T(); onCreate?.Invoke(val); return AddFacility((IFacility)(object)val); } public void AddHandlerSelector(IHandlerSelector selector) { NamingSubSystem.AddHandlerSelector(selector); } public void AddHandlersFilter(IHandlersFilter filter) { NamingSubSystem.AddHandlersFilter(filter); } public virtual void AddSubSystem(string name, ISubSystem subsystem) { if (name == null) throw new ArgumentNullException("name"); if (subsystem == null) throw new ArgumentNullException("subsystem"); subsystem.Init(this); subsystems[name] = subsystem; if (name == SubSystemConstants.ConversionManagerKey) ConversionSubSystem = (IConversionManager)subsystem; else if (name == SubSystemConstants.NamingKey) { NamingSubSystem = (INamingSubSystem)subsystem; } } public virtual IHandler[] GetAssignableHandlers(Type service) { IHandler[] array = NamingSubSystem.GetAssignableHandlers(service); if (Parent != null) { IHandler[] assignableHandlers = Parent.GetAssignableHandlers(service); if (assignableHandlers.Length != 0) { IHandler[] array2 = new IHandler[array.Length + assignableHandlers.Length]; array.CopyTo(array2, 0); assignableHandlers.CopyTo(array2, array.Length); array = array2; } } return array; } public virtual IFacility[] GetFacilities() { return facilities.ToArray(); } public virtual IHandler GetHandler(string name) { if (name == null) throw new ArgumentNullException("name"); IHandler handler = NamingSubSystem.GetHandler(name); if (handler == null && Parent != null) handler = WrapParentHandler(Parent.GetHandler(name)); return handler; } public virtual IHandler GetHandler(Type service) { if ((object)service == null) throw new ArgumentNullException("service"); IHandler handler = NamingSubSystem.GetHandler(service); if (handler == null && Parent != null) handler = WrapParentHandler(Parent.GetHandler(service)); return handler; } public virtual IHandler[] GetHandlers(Type service) { IHandler[] array = NamingSubSystem.GetHandlers(service); if (Parent != null) { IHandler[] handlers = Parent.GetHandlers(service); if (handlers.Length != 0) { IHandler[] array2 = new IHandler[array.Length + handlers.Length]; array.CopyTo(array2, 0); handlers.CopyTo(array2, array.Length); array = array2; } } return array; } public virtual IHandler[] GetHandlers() { IHandler[] array = NamingSubSystem.GetAllHandlers(); if (Parent != null) { IHandler[] handlers = Parent.GetHandlers(); if (handlers.Length != 0) { IHandler[] array2 = new IHandler[array.Length + handlers.Length]; array.CopyTo(array2, 0); handlers.CopyTo(array2, array.Length); array = array2; } } return array; } public virtual ISubSystem GetSubSystem(string name) { subsystems.TryGetValue(name, out ISubSystem value); return value; } public virtual bool HasComponent(string name) { if (name == null) return false; if (NamingSubSystem.Contains(name)) return true; if (Parent != null) return Parent.HasComponent(name); return false; } public virtual bool HasComponent(Type serviceType) { if ((object)serviceType == null) return false; if (NamingSubSystem.Contains(serviceType)) return true; if (Parent != null) return Parent.HasComponent(serviceType); return false; } public IKernel Register(params IRegistration[] registrations) { if (registrations == null) throw new ArgumentNullException("registrations"); IDisposable disposable = OptimizeDependencyResolution(); for (int i = 0; i < registrations.Length; i++) { registrations[i].Register(this); } disposable?.Dispose(); return this; } public virtual void ReleaseComponent(object instance) { if (ReleasePolicy.HasTrack(instance)) ReleasePolicy.Release(instance); else if (Parent != null) { Parent.ReleaseComponent(instance); } } public virtual void RemoveChildKernel(IKernel childKernel) { if (childKernel == null) throw new ArgumentNullException("childKernel"); childKernel.Parent = null; childKernels.Remove(childKernel); } public virtual ILifestyleManager CreateLifestyleManager(ComponentModel model, IComponentActivator activator) { ILifestyleManager lifestyleManager; switch (model.LifestyleType) { case LifestyleType.Scoped: lifestyleManager = new ScopedLifestyleManager(CreateScopeAccessor(model)); break; case LifestyleType.Bound: lifestyleManager = new ScopedLifestyleManager(CreateScopeAccessorForBoundLifestyle(model)); break; case LifestyleType.Thread: lifestyleManager = new ScopedLifestyleManager(new ThreadScopeAccessor()); break; case LifestyleType.Transient: lifestyleManager = new TransientLifestyleManager(); break; case LifestyleType.Custom: lifestyleManager = model.CustomLifestyle.CreateInstance<ILifestyleManager>(Array.Empty<object>()); break; case LifestyleType.Pooled: { int initialSize = ExtendedPropertiesConstants.Pool_Default_InitialPoolSize; int maxSize = ExtendedPropertiesConstants.Pool_Default_MaxPoolSize; if (model.ExtendedProperties.Contains(ExtendedPropertiesConstants.Pool_InitialPoolSize)) initialSize = (int)model.ExtendedProperties[ExtendedPropertiesConstants.Pool_InitialPoolSize]; if (model.ExtendedProperties.Contains(ExtendedPropertiesConstants.Pool_MaxPoolSize)) maxSize = (int)model.ExtendedProperties[ExtendedPropertiesConstants.Pool_MaxPoolSize]; lifestyleManager = new PoolableLifestyleManager(initialSize, maxSize); break; } default: lifestyleManager = new SingletonLifestyleManager(); break; } lifestyleManager.Init(activator, this, model); return lifestyleManager; } private static IScopeAccessor CreateScopeAccessor(ComponentModel model) { Type scopeAccessorType = model.GetScopeAccessorType(); if ((object)scopeAccessorType == null) return new LifetimeScopeAccessor(); return scopeAccessorType.CreateInstance<IScopeAccessor>(Array.Empty<object>()); } private IScopeAccessor CreateScopeAccessorForBoundLifestyle(ComponentModel model) { Func<IHandler[], IHandler> func = (Func<IHandler[], IHandler>)model.ExtendedProperties[Constants.ScopeRootSelector]; if (func == null) throw new ComponentRegistrationException($"""{model.Name}""{LifestyleType.Bound}"""); return new CreationContextScopeAccessor(model, func); } public virtual IComponentActivator CreateComponentActivator(ComponentModel model) { if (model == null) throw new ArgumentNullException("model"); if ((object)model.CustomComponentActivator != null) try { return model.CustomComponentActivator.CreateInstance<IComponentActivator>(new object[4] { model, this, new ComponentInstanceDelegate(RaiseComponentCreated), new ComponentInstanceDelegate(RaiseComponentDestroyed) }); } catch (Exception innerException) { throw new KernelException("Could not instantiate custom activator", innerException); } return new DefaultComponentActivator(model, this, RaiseComponentCreated, RaiseComponentDestroyed); } protected CreationContext CreateCreationContext(IHandler handler, Type requestedType, Arguments additionalArguments, CreationContext parent, IReleasePolicy policy) { return new CreationContext(handler, policy, requestedType, additionalArguments, ConversionSubSystem, parent); } protected void DisposeHandler(IHandler handler) { (handler as IDisposable)?.Dispose(); } void IKernelInternal.RaiseEventsOnHandlerCreated(IHandler handler) { RaiseHandlerRegistered(handler); RaiseHandlersChanged(); RaiseComponentRegistered(handler.ComponentModel.Name, handler); } protected virtual void RegisterSubSystems() { AddSubSystem(SubSystemConstants.ConfigurationStoreKey, new DefaultConfigurationStore()); AddSubSystem(SubSystemConstants.ConversionManagerKey, new DefaultConversionManager()); AddSubSystem(SubSystemConstants.NamingKey, new DefaultNamingSubSystem()); AddSubSystem(SubSystemConstants.ResourceKey, new DefaultResourceSubSystem()); AddSubSystem(SubSystemConstants.DiagnosticsKey, new DefaultDiagnosticsSubSystem()); } protected object ResolveComponent(IHandler handler, Type service, Arguments additionalArguments, IReleasePolicy policy) { return ResolveComponent(handler, service, additionalArguments, policy, false); } private object ResolveComponent(IHandler handler, Type service, Arguments additionalArguments, IReleasePolicy policy, bool ignoreParentContext) { CreationContext creationContext = currentCreationContext; CreationContext context = currentCreationContext = CreateCreationContext(handler, service, additionalArguments, ignoreParentContext ? null : creationContext, policy); try { return handler.Resolve(context); } finally { currentCreationContext = creationContext; } } protected virtual IHandler WrapParentHandler(IHandler parentHandler) { if (parentHandler == null) return null; ParentHandlerWrapper parentHandlerWrapper = new ParentHandlerWrapper(parentHandler, Parent.Resolver, Parent.ReleasePolicy); parentHandlerWrapper.Init(this); return parentHandlerWrapper; } private void DisposeComponentsInstancesWithinTracker() { ReleasePolicy.Dispose(); } private void DisposeHandlers() { IVertex[] graphNodes = GraphNodes; IVertex[] array = TopologicalSortAlgo.Sort(graphNodes); for (int i = 0; i < array.Length; i++) { ComponentModel componentModel = (ComponentModel)array[i]; IHandler handler = NamingSubSystem.GetHandler(componentModel.Name); DisposeHandler(handler); } } private void DisposeSubKernels() { foreach (IKernel childKernel in childKernels) { childKernel.Dispose(); } } private void HandlerRegisteredOnParentKernel(IHandler handler, ref bool stateChanged) { RaiseHandlerRegistered(handler); } private void HandlersChangedOnParentKernel(ref bool changed) { RaiseHandlersChanged(); } private void SubscribeToParentKernel() { if (parentKernel != null) { parentKernel.HandlerRegistered += this.HandlerRegisteredOnParentKernel; parentKernel.HandlersChanged += this.HandlersChangedOnParentKernel; parentKernel.ComponentRegistered += RaiseComponentRegistered; } } private void TerminateFacilities() { foreach (IFacility facility in facilities) { facility.Terminate(); } } private void UnsubscribeFromParentKernel() { if (parentKernel != null) { parentKernel.HandlerRegistered -= this.HandlerRegisteredOnParentKernel; parentKernel.HandlersChanged -= this.HandlersChangedOnParentKernel; parentKernel.ComponentRegistered -= RaiseComponentRegistered; } } IHandler IKernelInternal.LoadHandlerByName(string name, Type service, Arguments arguments) { if (name == null) throw new ArgumentNullException("name"); IHandler handler = GetHandler(name); if (handler != null) return handler; lock (lazyLoadingLock) { handler = GetHandler(name); if (handler == null) { if (!isCheckingLazyLoaders) { isCheckingLazyLoaders = true; try { ILazyComponentLoader[] array = ResolveAll<ILazyComponentLoader>(); for (int i = 0; i < array.Length; i++) { IRegistration registration = array[i].Load(name, service, arguments); if (registration != null) { registration.Register(this); return GetHandler(name); } } return null; } finally { isCheckingLazyLoaders = false; } } return null; } return handler; } } IHandler IKernelInternal.LoadHandlerByType(string name, Type service, Arguments arguments) { if ((object)service == null) throw new ArgumentNullException("service"); IHandler handler = GetHandler(service); if (handler != null) return handler; lock (lazyLoadingLock) { handler = GetHandler(service); if (handler == null) { if (!isCheckingLazyLoaders) { isCheckingLazyLoaders = true; try { ILazyComponentLoader[] array = ResolveAll<ILazyComponentLoader>(); for (int i = 0; i < array.Length; i++) { IRegistration registration = array[i].Load(name, service, arguments); if (registration != null) { registration.Register(this); return GetHandler(service); } } return null; } finally { isCheckingLazyLoaders = false; } } return null; } return handler; } } public IDisposable OptimizeDependencyResolution() { if (handlersChangedDeferred) return null; handlersChangedDeferred = true; return new OptimizeDependencyResolutionDisposable(this); } protected virtual void RaiseAddedAsChildKernel() { this.AddedAsChildKernel(this, EventArgs.Empty); } protected virtual void RaiseComponentCreated(ComponentModel model, object instance) { this.ComponentCreated(model, instance); } protected virtual void RaiseComponentDestroyed(ComponentModel model, object instance) { this.ComponentDestroyed(model, instance); } protected virtual void RaiseComponentModelCreated(ComponentModel model) { this.ComponentModelCreated(model); } protected virtual void RaiseComponentRegistered(string key, IHandler handler) { this.ComponentRegistered(key, handler); } protected virtual void RaiseDependencyResolving(ComponentModel client, DependencyModel model, object dependency) { this.DependencyResolving(client, model, dependency); } protected virtual void RaiseHandlerRegistered(IHandler handler) { bool stateChanged = true; while (stateChanged) { stateChanged = false; this.HandlerRegistered(handler, ref stateChanged); } } protected virtual void RaiseHandlersChanged() { if (handlersChangedDeferred) { lock (handlersChangedLock) { handlersChanged = true; } } else DoActualRaisingOfHandlersChanged(); } protected virtual void RaiseRegistrationCompleted() { this.RegistrationCompleted(this, EventArgs.Empty); } protected virtual void RaiseRemovedAsChildKernel() { this.RemovedAsChildKernel(this, EventArgs.Empty); } private void DoActualRaisingOfHandlersChanged() { bool stateChanged = true; while (stateChanged) { stateChanged = false; this.HandlersChanged(ref stateChanged); } } public virtual object Resolve(string key, Type service) { return ((IKernelInternal)this).Resolve(key, service, (Arguments)null, ReleasePolicy); } public virtual object Resolve(string key, Type service, Arguments arguments) { return ((IKernelInternal)this).Resolve(key, service, arguments, ReleasePolicy); } public T Resolve<T>(Arguments arguments) { return (T)Resolve(typeof(T), arguments); } public T Resolve<T>() { return (T)Resolve(typeof(T), null); } public T Resolve<T>(string key) { return (T)((IKernelInternal)this).Resolve(key, typeof(T), (Arguments)null, ReleasePolicy); } public T Resolve<T>(string key, Arguments arguments) { return (T)((IKernelInternal)this).Resolve(key, typeof(T), arguments, ReleasePolicy); } public object Resolve(Type service) { return ((IKernelInternal)this).Resolve(service, (Arguments)null, ReleasePolicy, false); } public object Resolve(Type service, Arguments arguments) { return ((IKernelInternal)this).Resolve(service, arguments, ReleasePolicy, false); } public Array ResolveAll(Type service) { return ((IKernelInternal)this).ResolveAll(service, (Arguments)null, ReleasePolicy); } public Array ResolveAll(Type service, Arguments arguments) { return ((IKernelInternal)this).ResolveAll(service, arguments, ReleasePolicy); } public TService[] ResolveAll<TService>(Arguments arguments) { return (TService[])((IKernelInternal)this).ResolveAll(typeof(TService), arguments, ReleasePolicy); } public TService[] ResolveAll<TService>() { return (TService[])((IKernelInternal)this).ResolveAll(typeof(TService), (Arguments)null, ReleasePolicy); } object IKernelInternal.Resolve(string key, Type service, Arguments arguments, IReleasePolicy policy) { IHandler handler = ((IKernelInternal)this).LoadHandlerByName(key, service, arguments); if (handler == null) { int countOfHandlersForTheService = GetHandlers(service).Length; throw new ComponentNotFoundException(key, service, countOfHandlersForTheService); } return ResolveComponent(handler, service ?? typeof(object), arguments, policy); } object IKernelInternal.Resolve(Type service, Arguments arguments, IReleasePolicy policy, bool ignoreParentContext) { IHandler handler = ((IKernelInternal)this).LoadHandlerByType((string)null, service, arguments); if (handler == null) throw new ComponentNotFoundException(service); return ResolveComponent(handler, service, arguments, policy, ignoreParentContext); } Array IKernelInternal.ResolveAll(Type service, Arguments arguments, IReleasePolicy policy) { List<object> list = new List<object>(); IHandler[] handlers = GetHandlers(service); foreach (IHandler handler in handlers) { if (!handler.IsBeingResolvedInContext(currentCreationContext)) try { object item = ResolveComponent(handler, service, arguments, policy); list.Add(item); } catch (GenericHandlerTypeMismatchException) { } } if (list.Count == 0) this.EmptyCollectionResolving(service); Array array = Array.CreateInstance(service, list.Count); ((ICollection)list).CopyTo(array, 0); return array; } } }