CreationContext
using Castle.Core;
using Castle.MicroKernel.Releasers;
using Castle.MicroKernel.SubSystems.Conversion;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Castle.MicroKernel
{
[Serializable]
public class CreationContext : MarshalByRefObject, ISubDependencyResolver
{
internal class RemoveDependencies : IDisposable
{
private readonly DependencyModelCollection dependencies;
private readonly DependencyModelCollection parentDependencies;
public RemoveDependencies(DependencyModelCollection dependencies, DependencyModelCollection parentDependencies)
{
this.dependencies = dependencies;
this.parentDependencies = parentDependencies;
}
public void Dispose()
{
if (parentDependencies != null) {
foreach (DependencyModel item in (Collection<DependencyModel>)parentDependencies) {
((Collection<DependencyModel>)dependencies).Remove(item);
}
}
}
}
public class ResolutionContext : IDisposable
{
private readonly CreationContext context;
private readonly Burden burden;
public Burden Burden => burden;
public ResolutionContext(CreationContext context, Burden burden)
{
this.context = context;
this.burden = burden;
}
public void Dispose()
{
context.ExitResolutionContext(burden);
}
}
private readonly IHandler handler;
private readonly IReleasePolicy releasePolicy;
private readonly IDictionary additionalArguments;
private readonly Type[] genericArguments;
private readonly DependencyModelCollection dependencies;
private readonly Stack<IHandler> handlerStack = new Stack<IHandler>();
private readonly Stack<ResolutionContext> resolutionStack = new Stack<ResolutionContext>();
private readonly ITypeConverter converter;
public static CreationContext Empty => new CreationContext();
public IReleasePolicy ReleasePolicy => releasePolicy;
public IDictionary AdditionalParameters => additionalArguments;
public bool HasAdditionalParameters => additionalArguments != null && additionalArguments.Count != 0;
public IHandler Handler => handler;
public DependencyModelCollection Dependencies => dependencies;
public Type[] GenericArguments => genericArguments;
public CreationContext(Type typeToExtractGenericArguments, CreationContext parentContext)
: this(parentContext.Handler, parentContext.ReleasePolicy, typeToExtractGenericArguments, null, null)
{
resolutionStack = parentContext.resolutionStack;
foreach (IHandler item in parentContext.handlerStack) {
handlerStack.Push(item);
}
}
public CreationContext(IHandler handler, IReleasePolicy releasePolicy, Type typeToExtractGenericArguments, IDictionary additionalArguments, ITypeConverter conversionManager)
{
this.handler = handler;
this.releasePolicy = releasePolicy;
this.additionalArguments = additionalArguments;
converter = conversionManager;
dependencies = new DependencyModelCollection();
genericArguments = ExtractGenericArguments(typeToExtractGenericArguments);
}
private CreationContext()
{
dependencies = new DependencyModelCollection();
releasePolicy = new NoTrackingReleasePolicy();
}
public virtual object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
if (additionalArguments == null)
return null;
object obj = additionalArguments[dependency.get_DependencyKey()];
if (obj == null || converter == null || dependency.get_TargetType().IsInstanceOfType(obj) || (int)dependency.get_DependencyType() != 1)
return obj;
return converter.PerformConversion(obj.ToString(), dependency.get_TargetType());
}
public virtual bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
if (dependency.get_DependencyKey() != null) {
if (additionalArguments == null)
return false;
object obj = additionalArguments[dependency.get_DependencyKey()];
if (obj == null || converter == null || dependency.get_TargetType().IsInstanceOfType(obj) || (int)dependency.get_DependencyType() != 1 || !converter.CanHandleType(dependency.get_TargetType()))
return additionalArguments.Contains(dependency.get_DependencyKey());
return true;
}
return false;
}
private static Type[] ExtractGenericArguments(Type typeToExtractGenericArguments)
{
return typeToExtractGenericArguments.GetGenericArguments();
}
public bool HandlerIsCurrentlyBeingResolved(IHandler handlerToTest)
{
return handlerStack.Contains(handlerToTest);
}
public ResolutionContext EnterResolutionContext(IHandler handlerBeingResolved)
{
return EnterResolutionContext(handlerBeingResolved, true);
}
public IDisposable ParentResolutionContext(CreationContext parent)
{
if (parent != null) {
dependencies.AddRange(parent.Dependencies);
return new RemoveDependencies(dependencies, parent.Dependencies);
}
return new RemoveDependencies(dependencies, null);
}
public ResolutionContext EnterResolutionContext(IHandler handlerBeingResolved, bool createBurden)
{
ResolutionContext resolutionContext = new ResolutionContext(this, createBurden ? new Burden() : null);
handlerStack.Push(handlerBeingResolved);
if (createBurden)
resolutionStack.Push(resolutionContext);
return resolutionContext;
}
private void ExitResolutionContext(Burden burden)
{
handlerStack.Pop();
if (burden != null) {
resolutionStack.Pop();
if (resolutionStack.Count != 0)
resolutionStack.Peek().Burden.AddChild(burden);
}
}
}
}