Burden
using Castle.Core;
using Castle.Core.Internal;
using Castle.MicroKernel.LifecycleConcerns;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Castle.MicroKernel
{
public class Burden
{
private enum Decommission : byte
{
No,
Yes,
LateBound
}
private readonly IHandler handler;
private Decommission decommission;
private List<Burden> dependencies;
public IHandler Handler => handler;
public object Instance { get; set; }
public ComponentModel Model => handler.ComponentModel;
public bool RequiresDecommission {
get {
return decommission != Decommission.No;
}
set {
if (value)
decommission = Decommission.Yes;
else
decommission = Decommission.No;
}
}
public bool RequiresPolicyRelease {
get {
if (!TrackedExternally)
return RequiresDecommission;
return false;
}
}
public bool TrackedExternally { get; set; }
public event BurdenReleaseDelegate Released;
public event BurdenReleaseDelegate Releasing;
public event BurdenReleaseDelegate GraphReleased;
internal Burden(IHandler handler, bool requiresDecommission, bool trackedExternally)
{
this.handler = handler;
TrackedExternally = trackedExternally;
if (requiresDecommission)
decommission = Decommission.Yes;
else if (Model.Lifecycle.HasDecommissionConcerns) {
if ((object)Model.Implementation == typeof(LateBoundComponent) && Model.Lifecycle.DecommissionConcerns.All(IsLateBound))
decommission = Decommission.LateBound;
else
decommission = Decommission.Yes;
}
}
public void AddChild(Burden child)
{
if (dependencies == null)
dependencies = new List<Burden>(Model.Dependents.Length);
dependencies.Add(child);
if (child.RequiresDecommission)
decommission = Decommission.Yes;
}
public bool Release()
{
this.Releasing?.Invoke(this);
if (!handler.Release(this))
return false;
this.Released?.Invoke(this);
if (dependencies != null)
dependencies.ForEach(delegate(Burden c) {
c.Release();
});
this.GraphReleased?.Invoke(this);
return true;
}
public void SetRootInstance(object instance)
{
if (instance == null)
throw new ArgumentNullException("instance");
Instance = instance;
if (decommission == Decommission.LateBound)
RequiresDecommission = (instance is IDisposable);
}
private bool IsLateBound(IDecommissionConcern arg)
{
return arg is LateBoundConcerns<IDecommissionConcern>;
}
}
}