Stashbox by Peter Csajtai

<PackageReference Include="Stashbox" Version="3.1.0-preview-542" />

 ResolutionStrategy

using Stashbox.Expressions; using Stashbox.Registration; using Stashbox.Resolution.Extensions; using Stashbox.Utils; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace Stashbox.Resolution { internal class ResolutionStrategy : IResolutionStrategy { private readonly ExpressionBuilder expressionBuilder; private ImmutableArray<IResolver> resolverRepository = ImmutableArray<IResolver>.Empty; private ImmutableArray<IResolver> lastChanceResolverRepository = ImmutableArray<IResolver>.Empty; public ResolutionStrategy(ExpressionBuilder expressionBuilder) { this.expressionBuilder = expressionBuilder; } public Expression BuildExpressionForType(ResolutionContext resolutionContext, TypeInformation typeInformation) { if (typeInformation.Type == Constants.ResolverType) return resolutionContext.CurrentScopeParameter.ConvertTo(Constants.ResolverType); if (typeInformation.Type == Constants.ServiceProviderType) return resolutionContext.CurrentScopeParameter.ConvertTo(Constants.ServiceProviderType); if (resolutionContext.ParameterExpressions.Length > 0) { int num = resolutionContext.ParameterExpressions.Length; while (num-- > 0) { KeyValue<bool, ParameterExpression>[] array = resolutionContext.ParameterExpressions[num].WhereOrDefault(delegate(KeyValue<bool, ParameterExpression> p) { if (!(p.Value.Type == typeInformation.Type)) return p.Value.Type.Implements(typeInformation.Type); return true; }); if (array != null) { KeyValue<bool, ParameterExpression> obj = array.FirstOrDefault((KeyValue<bool, ParameterExpression> parameter) => !parameter.Key) ?? array.Last(); obj.Key = true; return obj.Value; } } } Expression expressionOverrideOrDefault = resolutionContext.GetExpressionOverrideOrDefault(typeInformation.Type, typeInformation.DependencyName); if (expressionOverrideOrDefault != null) return expressionOverrideOrDefault; ServiceRegistration registrationOrDefault = resolutionContext.CurrentContainerContext.RegistrationRepository.GetRegistrationOrDefault(typeInformation, resolutionContext); if (registrationOrDefault == null) return BuildResolutionExpressionUsingResolvers(typeInformation, resolutionContext); return expressionBuilder.BuildExpressionAndApplyLifetime(registrationOrDefault, resolutionContext, typeInformation.Type); } public IEnumerable<Expression> BuildExpressionsForEnumerableRequest(ResolutionContext resolutionContext, TypeInformation typeInformation) { IEnumerable<ServiceRegistration> registrationsOrDefault = resolutionContext.CurrentContainerContext.RegistrationRepository.GetRegistrationsOrDefault(typeInformation, resolutionContext); ServiceRegistration[] array = (registrationsOrDefault != null) ? registrationsOrDefault.CastToArray() : null; if (array == null) return BuildAllResolverExpressionsUsingResolvers(typeInformation, resolutionContext); int num = array.Length; Expression[] array2 = new Expression[num]; for (int i = 0; i < num; i++) { array2[i] = expressionBuilder.BuildExpressionAndApplyLifetime(array[i], resolutionContext, typeInformation.Type); } return array2; } public Expression BuildExpressionForTopLevelRequest(Type type, object name, ResolutionContext resolutionContext) { if (type == Constants.ResolverType) return resolutionContext.CurrentScopeParameter.ConvertTo(Constants.ResolverType); if (type == Constants.ServiceProviderType) return resolutionContext.CurrentScopeParameter.ConvertTo(Constants.ServiceProviderType); Expression expressionOverrideOrDefault = resolutionContext.GetExpressionOverrideOrDefault(type, name); if (expressionOverrideOrDefault != null) return expressionOverrideOrDefault; ServiceRegistration registrationOrDefault = resolutionContext.CurrentContainerContext.RegistrationRepository.GetRegistrationOrDefault(type, resolutionContext, name); if (registrationOrDefault == null) return BuildResolutionExpressionUsingResolvers(new TypeInformation { Type = type, DependencyName = name }, resolutionContext); return expressionBuilder.BuildExpressionAndApplyLifetime(registrationOrDefault, resolutionContext, type); } public Expression BuildResolutionExpressionUsingResolvers(TypeInformation typeInfo, ResolutionContext resolutionContext) { Expression expression = resolverRepository.BuildResolutionExpression(typeInfo, resolutionContext, this); if (expression != null) return expression; return lastChanceResolverRepository.BuildResolutionExpression(typeInfo, resolutionContext, this); } public bool CanResolveType(TypeInformation typeInfo, ResolutionContext resolutionContext) { if (!resolverRepository.CanResolve(typeInfo, resolutionContext)) return lastChanceResolverRepository.CanResolve(typeInfo, resolutionContext); return true; } public void RegisterResolver(IResolver resolver) { Swap.SwapValue<IResolver, byte, byte, byte, ImmutableArray<IResolver>>(ref resolverRepository, (IResolver t1, byte t2, byte t3, byte t4, ImmutableArray<IResolver> repo) => repo.Add(t1), resolver, 0, 0, 0); } public void RegisterLastChanceResolver(IResolver resolver) { Swap.SwapValue<IResolver, byte, byte, byte, ImmutableArray<IResolver>>(ref lastChanceResolverRepository, (IResolver t1, byte t2, byte t3, byte t4, ImmutableArray<IResolver> repo) => repo.Add(t1), resolver, 0, 0, 0); } private IEnumerable<Expression> BuildAllResolverExpressionsUsingResolvers(TypeInformation typeInfo, ResolutionContext resolutionContext) { return resolverRepository.BuildAllResolutionExpressions(typeInfo, resolutionContext, this) ?? lastChanceResolverRepository.BuildAllResolutionExpressions(typeInfo, resolutionContext, this); } } }