StartableFacility
using Castle.MicroKernel;
using Castle.MicroKernel.Context;
using Castle.MicroKernel.Facilities;
using Castle.MicroKernel.SubSystems.Conversion;
using System;
namespace Castle.Facilities.Startable
{
public class StartableFacility : AbstractFacility
{
private class DeferredStartFlag : StartFlag
{
public override void Signal()
{
StartAll();
}
protected override void Init()
{
base.Init();
events.Kernel.RegistrationCompleted += delegate {
Signal();
};
}
}
private class DeferredTryStartFlag : DeferredStartFlag
{
protected override void Start(IHandler handler)
{
if (!TryStart(handler))
CacheHandler(handler);
}
private bool TryStart(IHandler handler)
{
return handler.TryResolve(CreationContext.CreateEmpty()) != null;
}
}
private class LegacyStartFlag : StartFlag
{
private bool inStart;
public override void Signal()
{
StartAll();
}
protected override void Init()
{
base.Init();
events.Kernel.ComponentRegistered += delegate {
if (!inStart)
Signal();
};
}
protected override void Start(IHandler handler)
{
if (!TryStart(handler))
CacheHandler(handler);
}
private bool TryStart(IHandler handler)
{
try {
inStart = true;
return handler.TryResolve(CreationContext.CreateEmpty()) != null;
} finally {
inStart = false;
}
}
}
public class StartableEvents
{
public IKernelEvents Kernel { get; set; }
public event Action<IHandler> StartableComponentRegistered = delegate {
};
public StartableEvents(IKernelEvents kernel)
{
Kernel = kernel;
kernel.ComponentRegistered += delegate(string key, IHandler handler) {
if (IsStartable(handler))
this.StartableComponentRegistered(handler);
};
}
}
private ITypeConverter converter;
private StartFlag flag;
public void DeferredStart()
{
DeferredStart(new DeferredStartFlag());
}
public void DeferredStart(StartFlag flag)
{
this.flag = flag;
}
public void DeferredTryStart()
{
DeferredStart(new DeferredTryStartFlag());
}
protected override void Init()
{
converter = base.Kernel.GetConversionManager();
base.Kernel.ComponentModelBuilder.AddContributor(new StartableContributor(converter));
InitFlag(flag ?? new LegacyStartFlag(), new StartableEvents(base.Kernel));
}
private void InitFlag(IStartFlagInternal startFlag, StartableEvents events)
{
startFlag.Init(events);
}
public static bool IsStartable(IHandler handler)
{
return ((bool?)handler.ComponentModel.ExtendedProperties["startable"]).GetValueOrDefault();
}
}
}