@@ -251,7 +251,7 @@ object IResolver.Resolve(Type serviceType, object serviceKey,
251251
252252 var currentScopeName = CurrentScope?.Name;
253253 if (currentScopeName != null)
254- cacheContextKey = cacheContextKey == null
254+ cacheContextKey = cacheContextKey == null
255255 ? currentScopeName
256256 : KV.Of(cacheContextKey, currentScopeName);
257257
@@ -627,7 +627,7 @@ void IResolverContext.UseInstance(Type serviceType, object instance, IfAlreadyRe
627627 var oldFactory = oldEntry as Factory;
628628 if (oldFactory != null)
629629 registry.DropFactoryCache(oldFactory, serviceType);
630- else
630+ else
631631 ((FactoriesEntry)oldEntry).Factories.Enumerate().ToArray()
632632 .DoPer(x => registry.DropFactoryCache(x.Value, serviceType, serviceKey));
633633 }
@@ -701,7 +701,7 @@ public IContainer With(Rules rules, IScopeContext scopeContext, RegistrySharing
701701 /// <param name="ignoreInsteadOfThrow">(optional) Controls what to do with the next registration: ignore or throw exception.
702702 /// Throws exception by default.</param>
703703 public IContainer WithNoMoreRegistrationAllowed(bool ignoreInsteadOfThrow = false) =>
704- new Container(Rules,
704+ new Container(Rules,
705705 Ref.Of(_registry.Value.WithNoMoreRegistrationAllowed(ignoreInsteadOfThrow)),
706706 _singletonScope, _scopeContext, _ownCurrentScope,
707707 _disposed, _disposeStackTrace, _parent, _root);
@@ -773,7 +773,7 @@ Factory IContainer.GetServiceFactoryOrDefault(Request request)
773773 Type serviceType;
774774 var requiredServiceType = request.RequiredServiceType;
775775 if (requiredServiceType != null && requiredServiceType.IsOpenGeneric())
776- serviceType = requiredServiceType;
776+ serviceType = requiredServiceType;
777777 else
778778 {
779779 // Special case when open-generic required service type is encoded in ServiceKey as array of { ReqOpenGenServiceType, ServiceKey }
@@ -826,7 +826,7 @@ Factory IContainer.GetServiceFactoryOrDefault(Request request)
826826 if (matchedFactories.Length == 1)
827827 {
828828 // Changes service key for resolution call to identify single factory in cache and prevent wrong hit
829- if (defaultFactories.Length > 1 && request.IsResolutionCall)
829+ if (defaultFactories.Length > 1 && request.IsResolutionCall)
830830 request.ChangeServiceKey(matchedFactories[0].Key);
831831
832832 return matchedFactories[0].Value;
@@ -919,7 +919,7 @@ Expr IContainer.GetDecoratorExpressionOrDefault(Request request)
919919
920920 var arrayElementType = request.ServiceType.GetArrayElementTypeOrNull();
921921 if (arrayElementType != null)
922- request = request.WithChangedServiceInfo(x =>
922+ request = request.WithChangedServiceInfo(x =>
923923 x.With(typeof(IEnumerable<>).MakeGenericType(arrayElementType)));
924924
925925 var container = request.Container;
@@ -1176,7 +1176,7 @@ private KV<object, Factory>[] GetRegisteredServiceFactoriesOrNull(Type serviceTy
11761176 return null;
11771177
11781178 var factory = entry as Factory;
1179- return factory != null
1179+ return factory != null
11801180 ? new KV<object, Factory>(DefaultKey.Value, factory).One()
11811181 : ((FactoriesEntry)entry).Factories.Enumerate().ToArray();
11821182 }
@@ -1402,13 +1402,18 @@ private Factory GetWrapperFactoryOrDefault(Request request)
14021402 return factory;
14031403 }
14041404
1405+ internal void SetScopedProvider(IServiceProvider serviceProvider)
1406+ {
1407+ _scopedProvider = serviceProvider;
1408+ }
1409+
14051410 #endregion
14061411
14071412 #region Implementation
14081413
14091414 private int _disposed;
14101415 private StackTrace _disposeStackTrace;
1411-
1416+ private IServiceProvider _scopedProvider;
14121417 internal readonly Ref<Registry> _registry;
14131418
14141419 private readonly IScope _singletonScope;
@@ -1422,6 +1427,8 @@ private Factory GetWrapperFactoryOrDefault(Request request)
14221427
14231428 internal bool PreferInterpretation => _preferInterpretation;
14241429
1430+ public IServiceProvider ScopedServiceProvider => _scopedProvider;
1431+
14251432 internal sealed class InstanceFactory : Factory
14261433 {
14271434 public override Type ImplementationType { get; }
@@ -1791,14 +1798,14 @@ public Registry Unregister(FactoryType factoryType, Type serviceType, object ser
17911798 Factory removedWrapper = null;
17921799 var registry = WithWrappers(Wrappers.Update(serviceType, null, (factory, _null) =>
17931800 {
1794- if (factory != null && condition != null && !condition(factory))
1801+ if (factory != null && condition != null && !condition(factory))
17951802 return factory;
17961803 removedWrapper = factory;
17971804 return null;
17981805
17991806 }));
18001807
1801- if (removedWrapper == null)
1808+ if (removedWrapper == null)
18021809 return this;
18031810 registry.DropFactoryCache(removedWrapper, serviceType);
18041811 return registry;
@@ -1811,7 +1818,7 @@ public Registry Unregister(FactoryType factoryType, Type serviceType, object ser
18111818 return removedDecorators == factories ? null : factories.Except(removedDecorators).ToArray();
18121819 }));
18131820
1814- if (removedDecorators.IsNullOrEmpty())
1821+ if (removedDecorators.IsNullOrEmpty())
18151822 return this;
18161823
18171824 foreach (var removedDecorator in removedDecorators)
@@ -1908,7 +1915,7 @@ private Registry UnregisterServiceFactory(Type serviceType, object serviceKey =
19081915
19091916 internal void DropFactoryCache(Factory factory, Type serviceType, object serviceKey = null)
19101917 {
1911- if (!DefaultFactoryDelegateCache.Value.IsEmpty ||
1918+ if (!DefaultFactoryDelegateCache.Value.IsEmpty ||
19121919 !KeyedFactoryDelegateCache.Value.IsEmpty)
19131920 {
19141921 if (factory.FactoryGenerator == null)
@@ -1943,7 +1950,7 @@ private Container(Rules rules, Ref<Registry> registry, IScope singletonScope,
19431950 _registry = registry;
19441951
19451952 _singletonScope = singletonScope;
1946-
1953+
19471954 _scopeContext = scopeContext;
19481955
19491956 if (_scopeContext == null && !FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagEnableEnhancedScopes))
@@ -2000,7 +2007,7 @@ public override bool Equals(object obj)
20002007 public override int GetHashCode() => ImTools.HashCode.Combine(RequiredServiceType, ServiceKey);
20012008
20022009 /// <inheritdoc />
2003- public Expr ToExpression(Func<object, Expr> fallbackConverter) =>
2010+ public Expr ToExpression(Func<object, Expr> fallbackConverter) =>
20042011 New(_ctor, Constant(RequiredServiceType, typeof(Type)), fallbackConverter(ServiceKey));
20052012
20062013 private static readonly ConstructorInfo _ctor = typeof(OpenGenericTypeKey).SingleConstructor();
@@ -3762,7 +3769,7 @@ public static FactoryMethodSelector Constructor(bool mostResolvable = false, boo
37623769
37633770 // First the check for normal resolution without Func<a, b, c>
37643771 if (!request.IsWrappedInFuncWithArgs())
3765- return Of(ctorsWithMaxParamsFirst.FindFirst(x =>
3772+ return Of(ctorsWithMaxParamsFirst.FindFirst(x =>
37663773 x.GetParameters().FindFirst(p => !IsResolvableParameter(p, paramSelector, request)) == null)
37673774 .ThrowIfNull(Error.UnableToFindCtorWithAllResolvableArgs, request));
37683775
@@ -3832,7 +3839,7 @@ public static FactoryMethodSelector Constructor(bool mostResolvable = false, boo
38323839 };
38333840
38343841 /// <summary>Easy way to specify default constructor to be used for resolution.</summary>
3835- public static FactoryMethodSelector DefaultConstructor(bool includeNonPublic = false) => request =>
3842+ public static FactoryMethodSelector DefaultConstructor(bool includeNonPublic = false) => request =>
38363843 request.ImplementationType.ThrowIfNull(Error.ImplTypeIsNotSpecifiedForAutoCtorSelection, request)
38373844 .GetConstructorOrNull(includeNonPublic, Empty<Type>())
38383845 ?.Do(ctor => Of(ctor));
@@ -4055,12 +4062,12 @@ private static TypedMade<TService> FromExpression<TService>(
40554062 var hasCustomValue = false;
40564063
40574064 var parameterSelector = parameters.IsNullOrEmpty() ? null
4058- : ComposeParameterSelectorFromArgs(ref hasCustomValue,
4065+ : ComposeParameterSelectorFromArgs(ref hasCustomValue,
40594066 serviceReturningExpr, parameters, argExprs, argValues);
40604067
40614068 var propertiesAndFieldsSelector =
40624069 memberBindingExprs == null || memberBindingExprs.Count == 0 ? null
4063- : ComposePropertiesAndFieldsSelector(ref hasCustomValue,
4070+ : ComposePropertiesAndFieldsSelector(ref hasCustomValue,
40644071 serviceReturningExpr, memberBindingExprs, argValues);
40654072
40664073 return new TypedMade<TService>(factoryMethod, parameterSelector, propertiesAndFieldsSelector, hasCustomValue);
@@ -4089,7 +4096,7 @@ private Made(FactoryMethodSelector factoryMethod = null, ParameterSelector param
40894096 }
40904097
40914098 private static ParameterSelector ComposeParameterSelectorFromArgs(ref bool hasCustomValue,
4092- Expression wholeServiceExpr, ParameterInfo[] paramInfos, IList<Expression> argExprs,
4099+ Expression wholeServiceExpr, ParameterInfo[] paramInfos, IList<Expression> argExprs,
40934100 params Func<Request, object>[] argValues)
40944101 {
40954102 var paramSelector = DryIoc.Parameters.Of;
@@ -4174,7 +4181,7 @@ private static PropertiesAndFieldsSelector ComposePropertiesAndFieldsSelector(re
41744181 }
41754182
41764183 private static Func<Request, object> GetArgCustomValueProvider(
4177- Expression wholeServiceExpr, MethodCallExpression methodCallExpr, Func<Request, object>[] argValues)
4184+ Expression wholeServiceExpr, MethodCallExpression methodCallExpr, Func<Request, object>[] argValues)
41784185 {
41794186 Throw.If(argValues.IsNullOrEmpty(), Error.ArgValueIndexIsProvidedButNoArgValues, wholeServiceExpr);
41804187
@@ -4925,7 +4932,7 @@ private static void PopulateDependencyResolutionCallExpressions(Request request)
49254932 if (factoryExpr == null)
49264933 return;
49274934
4928- request.Container.Rules.DependencyResolutionCallExprs.Swap(x =>
4935+ request.Container.Rules.DependencyResolutionCallExprs.Swap(x =>
49294936 x.AddOrUpdate(request, factoryExpr
49304937#if FEC_EXPRESSION_INFO
49314938 .ToExpression()
@@ -5383,7 +5390,7 @@ public override IServiceInfo Create(Type serviceType, ServiceDetails details) =>
53835390
53845391 public override void SetValue(object holder, object value) => _property.SetValue(holder, value, null);
53855392
5386- public override string ToString() =>
5393+ public override string ToString() =>
53875394 new StringBuilder().Print(this).Append(" as property ").Print(_property.Name, "\"").ToString();
53885395
53895396 private readonly PropertyInfo _property;
@@ -5409,7 +5416,7 @@ private class Field : PropertyOrFieldServiceInfo
54095416 {
54105417 public override Type ServiceType => _field.FieldType;
54115418
5412- public override IServiceInfo Create(Type serviceType, ServiceDetails details) =>
5419+ public override IServiceInfo Create(Type serviceType, ServiceDetails details) =>
54135420 serviceType == null ? new WithDetails(_field, details) : new TypeWithDetails(_field, serviceType, details);
54145421
54155422 public override MemberInfo Member => _field;
@@ -5630,7 +5637,7 @@ public Request Parent
56305637 public Type ServiceType => _serviceInfo.ServiceType;
56315638
56325639 /// <summary>Compatible required or service type.</summary>
5633- public Type GetActualServiceType() =>
5640+ public Type GetActualServiceType() =>
56345641 _actualServiceType ?? (_actualServiceType = _serviceInfo.GetActualServiceType());
56355642
56365643 private Type _actualServiceType; // saving result once
@@ -5672,8 +5679,8 @@ public Request Push(IServiceInfo info, RequestFlags additionalFlags = DefaultFla
56725679
56735680 /// <summary>Composes service description into <see cref="IServiceInfo"/> and Pushes the new request.</summary>
56745681 public Request Push(Type serviceType, object serviceKey = null,
5675- IfUnresolved ifUnresolved = IfUnresolved.Throw, Type requiredServiceType = null, RequestFlags flags = DefaultFlags) =>
5676- Push(ServiceInfo.Of(serviceType.ThrowIfNull().ThrowIf(serviceType.IsOpenGeneric(), Error.ResolvingOpenGenericServiceTypeIsNotPossible),
5682+ IfUnresolved ifUnresolved = IfUnresolved.Throw, Type requiredServiceType = null, RequestFlags flags = DefaultFlags) =>
5683+ Push(ServiceInfo.Of(serviceType.ThrowIfNull().ThrowIf(serviceType.IsOpenGeneric(), Error.ResolvingOpenGenericServiceTypeIsNotPossible),
56775684 requiredServiceType, ifUnresolved, serviceKey), flags);
56785685
56795686 #region Used in generated expression
@@ -5776,7 +5783,7 @@ public Request WithResolvedFactory(Factory factory,
57765783 }
57775784
57785785 // checking the service types only cause wrapper and decorators may be used multiple times
5779- if (!skipRecursiveDependencyCheck &&
5786+ if (!skipRecursiveDependencyCheck &&
57805787 factory.FactoryType == FactoryType.Service &&
57815788 HasRecursiveParent(factory.FactoryID))
57825789 Throw.It(Error.RecursiveDependencyDetected, Print(factory.FactoryID));
@@ -6529,7 +6536,7 @@ public virtual Expr GetExpressionOrDefault(Request request)
65296536 !request.IsResolutionCall && // preventing recursion
65306537 (Setup.AsResolutionCall || Setup.UseParentReuse || request.ShouldSplitObjectGraph()) &&
65316538 request.GetActualServiceType() != typeof(void)))
6532- return Resolver.CreateResolutionExpression(request, Setup.OpenResolutionScope);
6539+ return Resolver.CreateResolutionExpression(request, Setup.OpenResolutionScope);
65336540
65346541 // First look for decorators if it is not already a decorator
65356542 if (FactoryType != FactoryType.Decorator)
@@ -7083,14 +7090,14 @@ public override Expr CreateExpressionOrDefault(Request request)
70837090 var paramExpr = paramFactory?.GetExpressionOrDefault(paramRequest);
70847091 if (paramExpr == null ||
70857092 // When param is an empty array / collection, then we may use a default value instead (#581)
7086- paramInfo.Details.DefaultValue != null &&
7093+ paramInfo.Details.DefaultValue != null &&
70877094 paramExpr.NodeType == ExpressionType.NewArrayInit && ((NewArrayExpr)paramExpr).Expressions.Count == 0)
70887095 {
70897096 // Check if parameter dependency itself (without propagated parent details)
70907097 // does not allow default, then stop checking the rest of parameters.
70917098 if (paramInfo.Details.IfUnresolved == IfUnresolved.Throw)
70927099 return null;
7093-
7100+
70947101 var defaultValue = paramInfo.Details.DefaultValue;
70957102 paramExpr = defaultValue != null
70967103 ? container.GetConstantExpression(defaultValue)
@@ -7247,10 +7254,10 @@ public Factory GetGeneratedFactory(Request request, bool ifErrorReturnDefault =
72477254
72487255 if (implType != null)
72497256 {
7250- implType = implType.IsGenericParameter
7257+ implType = implType.IsGenericParameter
72517258 ? closedTypeArgs[0]
72527259 : Throw.IfThrows<ArgumentException, Type>(
7253- () => implType.MakeGenericType(closedTypeArgs),
7260+ () => implType.MakeGenericType(closedTypeArgs),
72547261 !ifErrorReturnDefault && request.IfUnresolved == IfUnresolved.Throw,
72557262 Error.NoMatchedGenericParamConstraints, implType, request);
72567263 if (implType == null)
@@ -7479,7 +7486,7 @@ private static void MatchOpenGenericConstraints(Type[] implTypeParams, Type[] im
74797486 continue; // skip yet unknown type arg
74807487
74817488 var implTypeParamConstraints = implTypeParams[i].GetGenericParamConstraints();
7482- if (implTypeParamConstraints.IsNullOrEmpty())
7489+ if (implTypeParamConstraints.IsNullOrEmpty())
74837490 continue; // skip case with no constraints
74847491
74857492 // match type parameters inside constraint
@@ -7843,7 +7850,7 @@ private object TryGetOrAdd(ImMap<object> items, int id, CreateScopedValue create
78437850 lock (_locker)
78447851 {
78457852 // re-check if items where changed in between (double check locking)
7846- if (_items != items && _items.TryFind(id, out item))
7853+ if (_items != items && _items.TryFind(id, out item))
78477854 return item;
78487855
78497856 item = createValue();
@@ -8067,7 +8074,7 @@ public Expr Apply(Request request, Expr serviceFactoryExpr) =>
80678074 Constant(request.FactoryID), Lambda<CreateScopedValue>(serviceFactoryExpr),
80688075 Constant(request.Factory.Setup.DisposalOrder));
80698076
8070- private static readonly Lazy<Expr> _singletonReuseExpr = Lazy.Of<Expr>(() =>
8077+ private static readonly Lazy<Expr> _singletonReuseExpr = Lazy.Of<Expr>(() =>
80718078 Field(null, typeof(Reuse).Field(nameof(Reuse.Singleton))));
80728079
80738080 /// <inheritdoc />
@@ -8268,11 +8275,11 @@ private ResolutionScopeName(Type serviceType, object serviceKey)
82688275 public bool Match(object scopeName)
82698276 {
82708277 var name = scopeName as ResolutionScopeName;
8271- return name != null &&
8278+ return name != null &&
82728279 (ServiceType == null ||
82738280 name.ServiceType.IsAssignableTo(ServiceType) ||
8274- ServiceType.IsOpenGeneric() &&
8275- name.ServiceType.GetGenericDefinitionOrNull().IsAssignableTo(ServiceType)) &&
8281+ ServiceType.IsOpenGeneric() &&
8282+ name.ServiceType.GetGenericDefinitionOrNull().IsAssignableTo(ServiceType)) &&
82768283 (ServiceKey == null || ServiceKey.Equals(name.ServiceKey));
82778284 }
82788285
@@ -8304,7 +8311,7 @@ public static class Reuse
83048311
83058312 /// <summary>Scoped to multiple names.</summary>
83068313 public static IReuse ScopedTo(params object[] names) =>
8307- names.IsNullOrEmpty() ? Scoped
8314+ names.IsNullOrEmpty() ? Scoped
83088315 : names.Length == 1 ? ScopedTo(names[0]) : new CurrentScopeReuse(CompositeScopeName.Of(names));
83098316
83108317 /// <summary>Same as InResolutionScopeOf. From now on will be the default name.</summary>
@@ -8535,6 +8542,8 @@ public enum RegistrySharing
85358542 /// <summary>Combines registrator and resolver roles, plus rules and scope management.</summary>
85368543 public interface IContainer : IRegistrator, IResolverContext
85378544 {
8545+ IServiceProvider ScopedServiceProvider { get; }
8546+
85388547 /// <summary>Rules for defining resolution/registration behavior throughout container.</summary>
85398548 Rules Rules { get; }
85408549
@@ -9538,7 +9547,7 @@ public static StringBuilder Print(this StringBuilder s, IEnumerable items,
95389547 /// <paramref name="getTypeName"/>Allows to specify if you want Name instead of FullName.</summary>
95399548 public static StringBuilder Print(this StringBuilder s, Type type, Func<Type, string> getTypeName = null)
95409549 {
9541- if (type == null)
9550+ if (type == null)
95429551 return s;
95439552
95449553 var isArray = type.IsArray;
0 commit comments