Stashbox by Peter Csajtai

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

 RegistrationRepository

using Stashbox.Configuration; using Stashbox.Exceptions; using Stashbox.Registration.Extensions; using Stashbox.Registration.SelectionRules; using Stashbox.Resolution; using Stashbox.Utils; using Stashbox.Utils.Data.Immutable; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; namespace Stashbox.Registration { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] internal class RegistrationRepository : IRegistrationRepository { private ImmutableTree<Type, ImmutableBucket<ServiceRegistration>> serviceRepository = ImmutableTree<Type, ImmutableBucket<ServiceRegistration>>.Empty; private readonly ContainerConfiguration containerConfiguration; private readonly IRegistrationSelectionRule[] filters = new IRegistrationSelectionRule[5] { RegistrationSelectionRules.GenericFilter, RegistrationSelectionRules.NameFilter, RegistrationSelectionRules.MetadataFilter, RegistrationSelectionRules.ScopeNameFilter, RegistrationSelectionRules.ConditionFilter }; private readonly IRegistrationSelectionRule[] topLevelFilters = new IRegistrationSelectionRule[4] { RegistrationSelectionRules.GenericFilter, RegistrationSelectionRules.NameFilter, RegistrationSelectionRules.MetadataFilter, RegistrationSelectionRules.ScopeNameFilter }; private readonly IRegistrationSelectionRule[] enumerableFilters = new IRegistrationSelectionRule[5] { RegistrationSelectionRules.GenericFilter, RegistrationSelectionRules.EnumerableNameFilter, RegistrationSelectionRules.ScopeNameFilter, RegistrationSelectionRules.ConditionFilter, RegistrationSelectionRules.MetadataFilter }; public RegistrationRepository(ContainerConfiguration containerConfiguration) { this.containerConfiguration = containerConfiguration; } public bool AddOrUpdateRegistration(ServiceRegistration registration, Type serviceType) { if (registration.Options.IsOn(RegistrationOption.ReplaceExistingRegistrationOnlyIfExists)) return Swap.SwapValue<ServiceRegistration, Type, byte, byte, ImmutableTree<Type, ImmutableBucket<ServiceRegistration>>>(ref serviceRepository, (ServiceRegistration reg, Type type, byte _, byte _, ImmutableTree<Type, ImmutableBucket<ServiceRegistration>> repo) => repo.UpdateIfExists(type, true, delegate(ImmutableBucket<ServiceRegistration> regs) { int num2 = -1; for (int j = 0; j < regs.Length; j++) { ServiceRegistration serviceRegistration3 = regs[j]; object obj3 = serviceRegistration3.Name ?? serviceRegistration3.ImplementationType; object obj4 = reg.Name ?? reg.ImplementationType; if (obj3.Equals(obj4)) num2 = j; } if (num2 != -1) { ServiceRegistration serviceRegistration4 = regs[num2]; reg.Replaces(serviceRegistration4); return regs.ReplaceAt(num2, reg); } return regs; }), registration, serviceType, 0, 0); return Swap.SwapValue(ref serviceRepository, (ServiceRegistration reg, Type type, ImmutableBucket<ServiceRegistration> newRepo, Rules.RegistrationBehavior regBehavior, ImmutableTree<Type, ImmutableBucket<ServiceRegistration>> repo) => repo.AddOrUpdate(type, newRepo, true, delegate(ImmutableBucket<ServiceRegistration> oldValue, ImmutableBucket<ServiceRegistration> _) { bool flag = reg.Options.IsOn(RegistrationOption.ReplaceExistingRegistration); bool flag2 = flag || regBehavior == Rules.RegistrationBehavior.ReplaceExisting; if (!flag2 && regBehavior == Rules.RegistrationBehavior.PreserveDuplications) return oldValue.Add(reg); int num = -1; for (int i = 0; i < oldValue.Length; i++) { ServiceRegistration serviceRegistration = oldValue[i]; if (flag || !(serviceRegistration.ImplementationType != reg.ImplementationType)) { object obj = serviceRegistration.Name ?? serviceRegistration.ImplementationType; object obj2 = reg.Name ?? reg.ImplementationType; if (obj.Equals(obj2)) num = i; } } if (num != -1) { if (!flag2) { if (regBehavior == Rules.RegistrationBehavior.ThrowException) throw new ServiceAlreadyRegisteredException(reg.ImplementationType, null); return oldValue; } ServiceRegistration serviceRegistration2 = oldValue[num]; reg.Replaces(serviceRegistration2); return oldValue.ReplaceAt(num, reg); } return oldValue.Add(reg); }), registration, serviceType, new ImmutableBucket<ServiceRegistration>(registration), containerConfiguration.RegistrationBehavior); } public bool AddOrReMapRegistration(ServiceRegistration registration, Type serviceType) { if (!registration.Options.IsOn(RegistrationOption.ReplaceExistingRegistrationOnlyIfExists)) return Swap.SwapValue<Type, ImmutableBucket<ServiceRegistration>, byte, byte, ImmutableTree<Type, ImmutableBucket<ServiceRegistration>>>(ref serviceRepository, (Type type, ImmutableBucket<ServiceRegistration> newRepo, byte _, byte _, ImmutableTree<Type, ImmutableBucket<ServiceRegistration>> repo) => repo.AddOrUpdate(type, newRepo, true, true), serviceType, new ImmutableBucket<ServiceRegistration>(registration), 0, 0); return Swap.SwapValue<Type, ImmutableBucket<ServiceRegistration>, byte, byte, ImmutableTree<Type, ImmutableBucket<ServiceRegistration>>>(ref serviceRepository, (Type type, ImmutableBucket<ServiceRegistration> newRepo, byte _, byte _, ImmutableTree<Type, ImmutableBucket<ServiceRegistration>> repo) => repo.UpdateIfExists(type, newRepo, true), serviceType, new ImmutableBucket<ServiceRegistration>(registration), 0, 0); } public bool ContainsRegistration(Type type, [System.Runtime.CompilerServices.Nullable(2)] object name, bool includeOpenGenerics = true) { return serviceRepository.ContainsRegistration(type, name, includeOpenGenerics); } [return: System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0, 1, 1 })] public IEnumerable<KeyValuePair<Type, ServiceRegistration>> GetRegistrationMappings() { return serviceRepository.Walk().SelectMany((ReadOnlyKeyValue<Type, ImmutableBucket<ServiceRegistration>> reg) => from r in reg.Value.Repository select new KeyValuePair<Type, ServiceRegistration>(reg.Key, r)); } [return: System.Runtime.CompilerServices.Nullable(2)] public ServiceRegistration GetRegistrationOrDefault(TypeInformation typeInfo, ResolutionContext resolutionContext) { IEnumerable<ServiceRegistration> registrationsForType = GetRegistrationsForType(typeInfo.Type); if (registrationsForType == null) return null; return registrationsForType.SelectOrDefault(typeInfo, resolutionContext, resolutionContext.IsTopRequest ? topLevelFilters : filters); } [return: System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1 })] public IEnumerable<ServiceRegistration> GetRegistrationsOrDefault(TypeInformation typeInfo, ResolutionContext resolutionContext) { IEnumerable<ServiceRegistration> registrationsForType = GetRegistrationsForType(typeInfo.Type); if (registrationsForType == null) return null; IEnumerable<ServiceRegistration> enumerable = registrationsForType.FilterExclusiveOrDefault(typeInfo, resolutionContext, enumerableFilters); if (enumerable == null) return null; return from reg in enumerable orderby reg.RegistrationOrder select reg; } [return: System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1 })] private IEnumerable<ServiceRegistration> GetRegistrationsForType(Type type) { IEnumerable<ServiceRegistration> enumerable = serviceRepository.GetOrDefaultByRef(type)?.Repository; if (!type.IsClosedGenericType()) return enumerable; ServiceRegistration[] array = serviceRepository.GetOrDefaultByRef(type.GetGenericTypeDefinition())?.Repository; if (array != null) { object enumerable2; if (enumerable != null) enumerable2 = array.Concat(enumerable); else { IEnumerable<ServiceRegistration> enumerable3 = array; enumerable2 = enumerable3; } enumerable = (IEnumerable<ServiceRegistration>)enumerable2; } ServiceRegistration[] array2 = serviceRepository.Walk().Where(delegate(ReadOnlyKeyValue<Type, ImmutableBucket<ServiceRegistration>> r) { if (r.Key.IsGenericType && r.Key.GetGenericTypeDefinition() == type.GetGenericTypeDefinition() && r.Key != type) return r.Key.ImplementsWithoutGenericCheck(type); return false; }).SelectMany((ReadOnlyKeyValue<Type, ImmutableBucket<ServiceRegistration>> r) => r.Value.Repository) .ToArray(); if (array2.Length != 0) { object enumerable4; if (enumerable != null) enumerable4 = array2.Concat(enumerable); else { IEnumerable<ServiceRegistration> enumerable3 = array2; enumerable4 = enumerable3; } enumerable = (IEnumerable<ServiceRegistration>)enumerable4; } return enumerable; } } }