using System; using System.Collections.Generic; using System.Linq; using System.Text; using Castle.Core; // ReSharper disable CheckNamespace namespace Castle.Windsor // ReSharper restore CheckNamespace { public class WindsorLifestyleConflict { public ComponentModel Component { get; private set; } public ComponentModel DependentComponent { get; private set; } public WindsorLifestyleConflict(ComponentModel component, ComponentModel dependentComponent) { if (component == null) throw new ArgumentNullException("component"); if (dependentComponent == null) throw new ArgumentNullException("dependentComponent"); Component = component; DependentComponent = dependentComponent; } } public class WindsorLifestyleConflictException : Exception { private readonly IEnumerable conflicts; public WindsorLifestyleConflictException(IEnumerable conflicts) { this.conflicts = conflicts; } public override string Message { get { var sb = new StringBuilder("The following lifestyle conflicts were detected:"); sb.AppendLine(); foreach (var conflict in conflicts) { sb.AppendLine(); sb.AppendFormat("\t {0} has a longer lifestyle than {1} ({2} > {3})", conflict.Component.Name, conflict.DependentComponent.Name, conflict.Component.LifestyleType, conflict.DependentComponent.LifestyleType); } return sb.ToString(); } } } public class WindsorLifestyleComparer : IComparer { private static readonly IDictionary LifestyleOrder = new Dictionary { {LifestyleType.Singleton, 5}, {LifestyleType.Undefined, 5}, {LifestyleType.Pooled, 4}, {LifestyleType.PerWebRequest, 3}, {LifestyleType.Thread, 2}, {LifestyleType.Custom, 1}, {LifestyleType.Transient, 0}, }; public int Compare(LifestyleType x, LifestyleType y) { return LifestyleOrder[x] - LifestyleOrder[y]; } } public static class WindsorExtensions { private static readonly WindsorLifestyleComparer LifestyleComparer = new WindsorLifestyleComparer(); public static void ValidateLifestyles(this IWindsorContainer container) { var conflicts = new List(); foreach (var node in container.Kernel.GraphNodes) { var component = (ComponentModel)node; foreach (var dependent in node.Dependents) { var dependentComponent = (ComponentModel)dependent; if (LifestyleComparer.Compare(component.LifestyleType, dependentComponent.LifestyleType) > 0) conflicts.Add(new WindsorLifestyleConflict(component, dependentComponent)); } } if (conflicts.Any()) throw new WindsorLifestyleConflictException(conflicts); } } }