AbstractHandler
public abstract class AbstractHandler : IHandler, ISubDependencyResolver, IExposeDependencyInfo, IDisposable
Implements the basis of
IHandler
using Castle.Core;
using Castle.MicroKernel.ComponentActivator;
using Castle.MicroKernel.Context;
using Castle.MicroKernel.Resolvers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace Castle.MicroKernel.Handlers
{
public abstract class AbstractHandler : IHandler, ISubDependencyResolver, IExposeDependencyInfo, IDisposable
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly ComponentModel model;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private IKernelInternal kernel;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private HashSet<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;
}
}
private ICollection<DependencyModel> MissingDependencies {
get {
if (missingDependencies == null)
missingDependencies = new HashSet<DependencyModel>();
return missingDependencies;
}
}
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)
inspector.Inspect(this, MissingDependencies.ToArray(), 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.Any((Type s) => (object)s == service);
}
public object TryResolve(CreationContext context)
{
try {
return Resolve(context, false);
} catch (DependencyResolverException) {
return null;
} catch (HandlerException) {
return null;
} catch (NoResolvableConstructorFoundException) {
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)
{
MissingDependencies.Add(dependency);
if (state != HandlerState.WaitingDependency) {
SetNewState(HandlerState.WaitingDependency);
Kernel.HandlersChanged += this.DependencySatisfied;
}
}
protected bool CanResolvePendingDependencies(CreationContext context)
{
if (CurrentState == HandlerState.Valid)
return true;
if (IsBeingResolvedInContext(context))
return CanProvideDependenciesDynamically(context);
DependencyModel[] array = MissingDependencies.ToArray();
foreach (DependencyModel dependencyModel in array) {
if ((object)dependencyModel.TargetItemType == 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)
{
DependencyModel[] array = MissingDependencies.ToArray();
foreach (DependencyModel dependencyModel in array) {
if (AddResolvableDependency(dependencyModel))
MissingDependencies.Remove(dependencyModel);
}
if (AllRequiredDependenciesResolvable()) {
SetNewState(HandlerState.Valid);
stateChanged = true;
DisconnectEvents();
missingDependencies = null;
}
}
protected virtual void EnsureDependenciesCanBeSatisfied(IDependencyAwareActivator activator)
{
if (activator == null || !activator.CanProvideRequiredDependencies(ComponentModel)) {
foreach (DependencyModel dependency in ComponentModel.Dependencies) {
AddDependency(dependency);
}
}
}
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 handler = dependency.GetHandler(Kernel);
if (handler != null)
ComponentModel.AddDependent(handler.ComponentModel);
}
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()
{
if (MissingDependencies.Count == 0)
return true;
List<ConstructorDependencyModel> list = MissingDependencies.OfType<ConstructorDependencyModel>().ToList();
if (MissingDependencies.Count != 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);
}
}
}