PotentialLifestyleMismatchesDiagnostic
public class PotentialLifestyleMismatchesDiagnostic : IPotentialLifestyleMismatchesDiagnostic, IDiagnostic<IHandler[][]>
using Castle.Core;
using Castle.Core.Internal;
using Castle.MicroKernel;
using System.Collections.Generic;
using System.Linq;
namespace Castle.Windsor.Diagnostics
{
public class PotentialLifestyleMismatchesDiagnostic : IPotentialLifestyleMismatchesDiagnostic, IDiagnostic<IHandler[][]>
{
private class MismatchedLifestyleDependency
{
private readonly HashSet<ComponentModel> checkedComponents;
public IHandler Handler { get; set; }
public MismatchedLifestyleDependency Parent { get; set; }
public MismatchedLifestyleDependency(IHandler handler, MismatchedLifestyleDependency parent = null)
{
Handler = handler;
Parent = parent;
if (parent == null)
checkedComponents = new HashSet<ComponentModel> {
handler.ComponentModel
};
else
checkedComponents = new HashSet<ComponentModel> {
parent.Handler.ComponentModel
};
}
public bool Checked(ComponentModel component)
{
return !checkedComponents.Add(component);
}
public IHandler[] GetHandlers()
{
List<IHandler> list = new List<IHandler>();
BuildHandlersList(list);
return list.ToArray();
}
public bool Mismatched()
{
if (Handler.ComponentModel.LifestyleType != LifestyleType.PerWebRequest)
return Handler.ComponentModel.LifestyleType == LifestyleType.Transient;
return true;
}
private void BuildHandlersList(List<IHandler> handlers)
{
if (Parent != null)
Parent.BuildHandlersList(handlers);
handlers.Add(Handler);
}
}
private readonly IKernel kernel;
public PotentialLifestyleMismatchesDiagnostic(IKernel kernel)
{
this.kernel = kernel;
}
public IHandler[][] Inspect()
{
IHandler[] assignableHandlers = kernel.GetAssignableHandlers(typeof(object));
Dictionary<ComponentModel, IHandler> model2Handler = assignableHandlers.ToDictionary((IHandler h) => h.ComponentModel);
List<MismatchedLifestyleDependency> list = new List<MismatchedLifestyleDependency>();
IHandler[] array = assignableHandlers;
foreach (IHandler handler in array) {
list.AddRange(GetMismatches(handler, model2Handler));
}
return list.ConvertAll((MismatchedLifestyleDependency m) => m.GetHandlers()).ToArray();
}
private IEnumerable<MismatchedLifestyleDependency> GetMismatch(MismatchedLifestyleDependency parent, ComponentModel component, IDictionary<ComponentModel, IHandler> model2Handler)
{
if (!parent.Checked(component)) {
IHandler handler = model2Handler[component];
MismatchedLifestyleDependency item = new MismatchedLifestyleDependency(handler, parent);
if (item.Mismatched())
yield return item;
else
try {
GraphNode[] dependents = handler.ComponentModel.Dependents;
for (int i = 0; i < dependents.Length; i++) {
ComponentModel dependent = (ComponentModel)dependents[i];
foreach (MismatchedLifestyleDependency item2 in GetMismatch(item, dependent, model2Handler)) {
yield return item2;
}
}
} finally {
}
}
}
private IEnumerable<MismatchedLifestyleDependency> GetMismatches(IHandler handler, IDictionary<ComponentModel, IHandler> model2Handler)
{
if (IsSingleton(handler)) {
MismatchedLifestyleDependency root = new MismatchedLifestyleDependency(handler, null);
try {
GraphNode[] dependents = handler.ComponentModel.Dependents;
for (int i = 0; i < dependents.Length; i++) {
ComponentModel dependent = (ComponentModel)dependents[i];
foreach (MismatchedLifestyleDependency item in GetMismatch(root, dependent, model2Handler)) {
yield return item;
}
}
} finally {
}
}
}
private bool IsSingleton(IHandler component)
{
LifestyleType lifestyleType = component.ComponentModel.LifestyleType;
if (lifestyleType != 0)
return lifestyleType == LifestyleType.Singleton;
return true;
}
}
}