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

AbstractHandler

Implements the basis of IHandler
using Castle.Core; using Castle.Core.Internal; using Castle.MicroKernel.Context; using Castle.MicroKernel.Resolvers; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Threading; namespace Castle.MicroKernel.Handlers { [Serializable] public abstract class AbstractHandler : MarshalByRefObject, IHandler, ISubDependencyResolver, IExposeDependencyInfo, IDisposable { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ComponentModel model; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private IKernelInternal kernel; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private SimpleThreadSafeSet<DependencyModel> missingDependencies; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private HandlerState state; [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public ComponentModel ComponentModel { get { return model; } } public HandlerState CurrentState => state; [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected IKernelInternal Kernel { get { return kernel; } } protected AbstractHandler(ComponentModel model) { this.model = model; } public abstract bool ReleaseCore(Burden burden); protected abstract object Resolve(CreationContext context, bool instanceRequired); public override string ToString() { return $"""{model}"; } public virtual void Dispose() { } public void ObtainDependencyDetails(IDependencyInspector inspector) { if (CurrentState != 0) { SimpleThreadSafeSet<DependencyModel> simpleThreadSafeSet = missingDependencies; inspector.Inspect(this, (simpleThreadSafeSet != null) ? simpleThreadSafeSet.ToArray() : new DependencyModel[0], Kernel); } } private bool HasCustomParameter(object key) { if (key == null) return false; return model.CustomDependencies.Contains(key); } public virtual void Init(IKernelInternal kernel) { if (kernel == null) throw new ArgumentNullException("kernel"); this.kernel = kernel; this.kernel.AddedAsChildKernel += OnAddedAsChildKernel; InitDependencies(); if (AllRequiredDependenciesResolvable()) { SetNewState(HandlerState.Valid); DisconnectEvents(); missingDependencies = null; } } protected virtual void InitDependencies() { foreach (DependencyModel dependency in ComponentModel.Dependencies) { AddDependency(dependency); } } public bool IsBeingResolvedInContext(CreationContext context) { return context?.IsInResolutionContext(this) ?? false; } public virtual bool Release(Burden burden) { return ReleaseCore(burden); } public object Resolve(CreationContext context) { return Resolve(context, true); } public virtual bool Supports(Type service) { return ComponentModel.Services.Contains(service); } public virtual bool SupportsAssignable(Type service) { IEnumerable<Type> services = ComponentModel.Services; TypeInfo typeInfo = service.GetTypeInfo(); return services.Any(typeInfo.IsAssignableFrom); } public object TryResolve(CreationContext context) { try { return Resolve(context, false); } catch (DependencyResolverException exception) { Kernel.Logger.Warn($"""{ComponentModel.Name}""", exception); return null; } catch (HandlerException exception2) { Kernel.Logger.Warn($"""{ComponentModel.Name}""", exception2); return null; } } public virtual bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { if (!this.model.HasCustomDependencies) return false; if (!HasCustomParameter(dependency.DependencyKey)) return HasCustomParameter(dependency.TargetItemType); return true; } public virtual object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { if (HasCustomParameter(dependency.DependencyKey)) return model.CustomDependencies[dependency.DependencyKey]; return model.CustomDependencies[dependency.TargetItemType]; } protected void AddDependency(DependencyModel dependency) { dependency.Init(model.ParametersInternal); if (!AddOptionalDependency(dependency) && !AddResolvableDependency(dependency)) AddMissingDependency(dependency); } protected void AddMissingDependency(DependencyModel dependency) { SimpleThreadSafeSet<DependencyModel> simpleThreadSafeSet = missingDependencies; if (simpleThreadSafeSet == null) { SimpleThreadSafeSet<DependencyModel> simpleThreadSafeSet2 = new SimpleThreadSafeSet<DependencyModel>(); simpleThreadSafeSet = (Interlocked.CompareExchange(ref missingDependencies, simpleThreadSafeSet2, null) ?? simpleThreadSafeSet2); } simpleThreadSafeSet.Add(dependency); if (state != HandlerState.WaitingDependency) { SetNewState(HandlerState.WaitingDependency); Kernel.HandlersChanged += this.DependencySatisfied; } } protected bool CanResolvePendingDependencies(CreationContext context) { SimpleThreadSafeSet<DependencyModel> simpleThreadSafeSet = missingDependencies; if (CurrentState == HandlerState.Valid || simpleThreadSafeSet == null) return true; DependencyModel[] array = simpleThreadSafeSet.ToArray(); foreach (DependencyModel dependencyModel in array) { if (dependencyModel.TargetItemType == (Type)null) return CanProvideDependenciesDynamically(context); IHandler handler = Kernel.GetHandler(dependencyModel.TargetItemType); if (handler == this || handler == null) return CanProvideDependenciesDynamically(context); } return true; } private bool CanProvideDependenciesDynamically(CreationContext context) { if (!context.HasAdditionalArguments) return kernel.HasComponent(typeof(ILazyComponentLoader)); return true; } protected void DependencySatisfied(ref bool stateChanged) { SimpleThreadSafeSet<DependencyModel> simpleThreadSafeSet = missingDependencies; if (simpleThreadSafeSet != null) { DependencyModel[] array = simpleThreadSafeSet.ToArray(); foreach (DependencyModel dependencyModel in array) { if (AddResolvableDependency(dependencyModel)) simpleThreadSafeSet.Remove(dependencyModel); } if (AllRequiredDependenciesResolvable()) { SetNewState(HandlerState.Valid); stateChanged = true; DisconnectEvents(); missingDependencies = null; } } } protected void OnAddedAsChildKernel(object sender, EventArgs e) { bool stateChanged = false; DependencySatisfied(ref stateChanged); } protected void SetNewState(HandlerState newState) { state = newState; } private void AddGraphDependency(DependencyModel dependency) { IHandler dependencyHandler = GetDependencyHandler(dependency); if (dependencyHandler != null) ComponentModel.AddDependent(dependencyHandler.ComponentModel); } private IHandler GetDependencyHandler(DependencyModel dependency) { if (dependency.ReferencedComponentName != null) return Kernel.GetHandler(dependency.ReferencedComponentName); if (dependency.TargetItemType != (Type)null) return Kernel.GetHandler(dependency.TargetItemType); return null; } private bool AddOptionalDependency(DependencyModel dependency) { if (dependency.IsOptional || dependency.HasDefaultValue) { AddGraphDependency(dependency); return true; } return false; } private bool AddResolvableDependency(DependencyModel dependency) { if (HasValidComponentFromResolver(dependency)) { AddGraphDependency(dependency); return true; } return false; } private bool AllRequiredDependenciesResolvable() { SimpleThreadSafeSet<DependencyModel> simpleThreadSafeSet = missingDependencies; if (simpleThreadSafeSet == null) return true; DependencyModel[] array = simpleThreadSafeSet.ToArray(); if (array.Length == 0) return true; List<ConstructorDependencyModel> list = array.OfType<ConstructorDependencyModel>().ToList(); if (array.Length != list.Count) return false; int num = (from d in list select d.Constructor).Distinct().Count(); return model.Constructors.Count > num; } private void DisconnectEvents() { Kernel.HandlersChanged -= this.DependencySatisfied; Kernel.AddedAsChildKernel -= OnAddedAsChildKernel; } private bool HasValidComponentFromResolver(DependencyModel dependency) { return Kernel.Resolver.CanResolve(CreationContext.ForDependencyInspection(this), this, model, dependency); } } }