<PackageReference Include="Castle.Windsor" Version="3.0.0.2001" />

PotentialLifestyleMismatchesDiagnostic

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; } } }