Stashbox by Peter Csajtai

<PackageReference Include="Stashbox" Version="3.6.2-preview-635" />

 OpenGenericRegistration

using Stashbox.Configuration; using Stashbox.Utils; using Stashbox.Utils.Data.Immutable; using System; namespace Stashbox.Registration { internal class OpenGenericRegistration : ServiceRegistration { private ImmutableTree<Type, ServiceRegistration> closedGenericRegistrations = ImmutableTree<Type, ServiceRegistration>.Empty; internal OpenGenericRegistration(Type implementationType, ContainerConfiguration containerConfiguration, RegistrationContext registrationContext, bool isDecorator) : base(implementationType, RegistrationType.OpenGeneric, containerConfiguration, registrationContext, isDecorator) { } public ServiceRegistration ProduceClosedRegistration(Type requestedType) { ServiceRegistration orDefaultByRef = closedGenericRegistrations.GetOrDefaultByRef(requestedType); if (orDefaultByRef != null) return orDefaultByRef; ServiceRegistration serviceRegistration = new ServiceRegistration(base.ImplementationType.MakeGenericType(requestedType.GetGenericArguments()), RegistrationType.Default, Configuration, base.RegistrationContext, base.IsDecorator); serviceRegistration.RegistrationContext.Name = null; if (Swap.SwapValue<Type, ServiceRegistration, byte, byte, ImmutableTree<Type, ServiceRegistration>>(ref closedGenericRegistrations, (Type t1, ServiceRegistration t2, byte t3, byte t4, ImmutableTree<Type, ServiceRegistration> items) => items.AddOrUpdate(t1, t2, true, null), requestedType, serviceRegistration, 0, 0)) return serviceRegistration; return closedGenericRegistrations.GetOrDefaultByRef(requestedType); } } }