DuplicatedDependenciesDiagnostic
public class DuplicatedDependenciesDiagnostic : IDuplicatedDependenciesDiagnostic, IDiagnostic<Pair<IHandler, DependencyDuplicate[]>[]>
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);
}
}
}