Stashbox by Peter Csajtai

<PackageReference Include="Stashbox" Version="3.6.3" />

 ServiceRepositoryExtensions

using Stashbox.Registration.SelectionRules; using Stashbox.Resolution; using Stashbox.Utils.Data; using Stashbox.Utils.Data.Immutable; using System; using System.Collections.Generic; using System.Linq; namespace Stashbox.Registration.Extensions { internal static class ServiceRepositoryExtensions { public static bool ContainsRegistration(this ImmutableTree<Type, ImmutableBucket<object, ServiceRegistration>> repository, Type type, object name) { ImmutableBucket<object, ServiceRegistration> orDefaultByRef = repository.GetOrDefaultByRef(type); if (name != null && orDefaultByRef != null) return orDefaultByRef.GetOrDefaultByValue(name) != null; if (orDefaultByRef != null || !type.IsClosedGenericType()) return orDefaultByRef != null; orDefaultByRef = repository.GetOrDefaultByRef(type.GetGenericTypeDefinition()); if (orDefaultByRef == null) return false; return orDefaultByRef.Any((ServiceRegistration reg) => type.SatisfiesGenericConstraintsOf(reg.ImplementationTypeInfo)); } public static ServiceRegistration SelectOrDefault(this IEnumerable<ServiceRegistration> registrations, TypeInformation typeInformation, ResolutionContext resolutionContext, IRegistrationSelectionRule[] registrationSelectionRules) { int num = 0; ServiceRegistration result = null; foreach (ServiceRegistration registration in registrations) { if (registrationSelectionRules.IsSelectionPassed(typeInformation, registration, resolutionContext, out int weight) && weight >= num) { num = weight; result = registration; } } return result; } public static IEnumerable<ServiceRegistration> FilterExclusiveOrDefault(this IEnumerable<ServiceRegistration> registrations, TypeInformation typeInformation, ResolutionContext resolutionContext, IRegistrationSelectionRule[] registrationSelectionRules) { ExpandableArray<ServiceRegistration> expandableArray = new ExpandableArray<ServiceRegistration>(); ExpandableArray<ServiceRegistration> expandableArray2 = new ExpandableArray<ServiceRegistration>(); foreach (ServiceRegistration registration in registrations) { if (registrationSelectionRules.IsSelectionPassed(typeInformation, registration, resolutionContext, out int weight)) { if (weight > 0) expandableArray2.Add(registration); else expandableArray.Add(registration); } } if (expandableArray.Length == 0 && expandableArray2.Length == 0) return null; if (expandableArray2.Length <= 0) return expandableArray; return expandableArray2; } public static IEnumerable<ServiceRegistration> FilterInclusiveOrDefault(this IEnumerable<ServiceRegistration> registrations, TypeInformation typeInformation, ResolutionContext resolutionContext, IRegistrationSelectionRule[] registrationSelectionRules) { int weight; return from serviceRegistration in registrations where registrationSelectionRules.IsSelectionPassed(typeInformation, serviceRegistration, resolutionContext, out weight) select serviceRegistration; } private static bool IsSelectionPassed(this IRegistrationSelectionRule[] registrationSelectionRules, TypeInformation typeInformation, ServiceRegistration serviceRegistration, ResolutionContext resolutionContext, out int weight) { weight = 0; int num = registrationSelectionRules.Length; for (int i = 0; i < num; i++) { if (!registrationSelectionRules[i].IsValidForCurrentRequest(typeInformation, serviceRegistration, resolutionContext)) return false; if (registrationSelectionRules[i].ShouldIncrementWeight(typeInformation, serviceRegistration, resolutionContext)) weight++; } return true; } } }