StartableFacility
using Castle.MicroKernel;
using Castle.MicroKernel.Context;
using Castle.MicroKernel.Facilities;
using Castle.MicroKernel.SubSystems.Conversion;
using System;
using System.Collections.Generic;
namespace Castle.Facilities.Startable
{
public class StartableFacility : AbstractFacility
{
private readonly List<IHandler> waitList = new List<IHandler>();
private ITypeConverter converter;
private bool disableException;
private bool inStart;
private bool optimizeForSingleInstall;
public void DeferredStart()
{
optimizeForSingleInstall = true;
disableException = false;
}
public void DeferredTryStart()
{
optimizeForSingleInstall = true;
disableException = true;
}
protected override void Init()
{
converter = base.Kernel.GetConversionManager();
base.Kernel.ComponentModelBuilder.AddContributor(new StartableContributor(converter));
if (optimizeForSingleInstall) {
base.Kernel.RegistrationCompleted += StartAll;
base.Kernel.ComponentRegistered += CacheForStart;
} else
base.Kernel.ComponentRegistered += OnComponentRegistered;
}
private void AddHandlerToWaitingList(IHandler handler)
{
waitList.Add(handler);
}
private void CacheForStart(string key, IHandler handler)
{
if (IsStartable(handler))
waitList.Add(handler);
}
private void CheckWaitingList()
{
if (!inStart) {
IHandler[] array = waitList.ToArray();
IHandler[] array2 = array;
foreach (IHandler handler in array2) {
if (TryStart(handler))
waitList.Remove(handler);
}
}
}
private bool IsStartable(IHandler handler)
{
object obj = handler.ComponentModel.ExtendedProperties["startable"];
return ((bool?)obj).GetValueOrDefault();
}
private void OnComponentRegistered(string key, IHandler handler)
{
if (IsStartable(handler) && !TryStart(handler))
AddHandlerToWaitingList(handler);
CheckWaitingList();
}
private void Start(IHandler handler)
{
handler.Resolve(CreationContext.CreateEmpty());
}
private void StartAll(object sender, EventArgs e)
{
IHandler[] array = waitList.ToArray();
waitList.Clear();
IHandler[] array2 = array;
foreach (IHandler handler in array2) {
if (!disableException)
Start(handler);
else if (!TryStart(handler)) {
AddHandlerToWaitingList(handler);
}
}
}
private bool TryStart(IHandler handler)
{
try {
inStart = true;
return handler.TryResolve(CreationContext.CreateEmpty()) != null;
} finally {
inStart = false;
}
}
}
}