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

DuplicatedDependenciesDiagnostic

using Castle.Core; using Castle.Core.Internal; using Castle.MicroKernel; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Castle.Windsor.Diagnostics { public class DuplicatedDependenciesDiagnostic : IDuplicatedDependenciesDiagnostic, IDiagnostic<Pair<IHandler, DependencyDuplicate[]>[]> { private readonly IKernel kernel; public DuplicatedDependenciesDiagnostic(IKernel kernel) { this.kernel = kernel; } public string GetDetails(DependencyDuplicate duplicates) { StringBuilder stringBuilder = new StringBuilder(); Describe(stringBuilder, duplicates.Dependency1); stringBuilder.Append(" duplicates "); Describe(stringBuilder, duplicates.Dependency2); switch (duplicates.Reason) { case DependencyDuplicationReason.Name: stringBuilder.Append(", they both have the same name."); break; case DependencyDuplicationReason.Type: stringBuilder.Append(", they both have the same type."); break; case DependencyDuplicationReason.NameAndType: stringBuilder.Append(", they both have the same name and type."); break; case DependencyDuplicationReason.Reference: stringBuilder.Append(", they both reference the same component " + duplicates.Dependency1.ReferencedComponentName); break; } return stringBuilder.ToString(); } public Pair<IHandler, DependencyDuplicate[]>[] Inspect() { IHandler[] assignableHandlers = kernel.GetAssignableHandlers(typeof(object)); List<Pair<IHandler, DependencyDuplicate[]>> list = new List<Pair<IHandler, DependencyDuplicate[]>>(); IHandler[] array = assignableHandlers; foreach (IHandler handler in array) { DependencyDuplicate[] array2 = FindDuplicateDependenciesFor(handler); if (array2.Length != 0) list.Add(new Pair<IHandler, DependencyDuplicate[]>(handler, array2)); } return list.ToArray(); } private void CollectDuplicatesBetween(DependencyModel[] array, ICollection<DependencyDuplicate> duplicates) { for (int i = 0; i < array.Length; i++) { for (int j = i + 1; j < array.Length; j++) { DependencyDuplicationReason dependencyDuplicationReason = IsDuplicate(array[i], array[j]); if (dependencyDuplicationReason != 0) duplicates.Add(new DependencyDuplicate(array[i], array[j], dependencyDuplicationReason)); } } } private void CollectDuplicatesBetweenConstructorParameters(ConstructorCandidateCollection constructors, ICollection<DependencyDuplicate> duplicates) { foreach (ConstructorCandidate constructor in constructors) { DependencyModel[] dependencies = constructor.Dependencies; CollectDuplicatesBetween(dependencies, duplicates); } } private void CollectDuplicatesBetweenProperties(DependencyModel[] properties, ICollection<DependencyDuplicate> duplicates) { CollectDuplicatesBetween(properties, duplicates); } private void CollectDuplicatesBetweenPropertiesAndConstructors(ConstructorCandidateCollection constructors, DependencyModel[] properties, ICollection<DependencyDuplicate> duplicates) { foreach (ConstructorCandidate constructor in constructors) { ConstructorDependencyModel[] dependencies = constructor.Dependencies; foreach (ConstructorDependencyModel constructorDependencyModel in dependencies) { foreach (DependencyModel dependencyModel in properties) { DependencyDuplicationReason dependencyDuplicationReason = IsDuplicate(dependencyModel, constructorDependencyModel); if (dependencyDuplicationReason != 0) duplicates.Add(new DependencyDuplicate(dependencyModel, constructorDependencyModel, dependencyDuplicationReason)); } } } } private DependencyDuplicate[] FindDuplicateDependenciesFor(IHandler handler) { HashSet<DependencyDuplicate> hashSet = new HashSet<DependencyDuplicate>(); DependencyModel[] properties = (from p in handler.ComponentModel.Properties select p.Dependency into d orderby d.ToString() select d).ToArray(); ConstructorCandidateCollection constructors = handler.ComponentModel.Constructors; CollectDuplicatesBetweenProperties(properties, hashSet); CollectDuplicatesBetweenConstructorParameters(constructors, hashSet); CollectDuplicatesBetweenPropertiesAndConstructors(constructors, properties, hashSet); return hashSet.ToArray(); } private DependencyDuplicationReason IsDuplicate(DependencyModel foo, DependencyModel bar) { if ((foo.ReferencedComponentName != null || bar.ReferencedComponentName != null) && string.Equals(foo.ReferencedComponentName, bar.ReferencedComponentName, StringComparison.OrdinalIgnoreCase)) return DependencyDuplicationReason.Reference; if (string.Equals(foo.DependencyKey, bar.DependencyKey, StringComparison.OrdinalIgnoreCase)) { if (foo.TargetItemType == bar.TargetItemType) return DependencyDuplicationReason.NameAndType; return DependencyDuplicationReason.Name; } if (foo.TargetItemType == bar.TargetItemType) return DependencyDuplicationReason.Type; return DependencyDuplicationReason.Unspecified; } private static void Describe(StringBuilder details, DependencyModel dependency) { if (dependency is PropertyDependencyModel) details.Append("Property "); else if (dependency is ConstructorDependencyModel) { details.Append("Constructor parameter "); } else { details.Append("Depdendency "); } details.Append(dependency.TargetItemType.ToCSharpString() + " " + dependency.DependencyKey); } } }