@@ -251,7 +251,7 @@ object IResolver.Resolve(Type serviceType, object serviceKey,
251
251
252
252
var currentScopeName = CurrentScope?.Name;
253
253
if (currentScopeName != null)
254
- cacheContextKey = cacheContextKey == null
254
+ cacheContextKey = cacheContextKey == null
255
255
? currentScopeName
256
256
: KV.Of(cacheContextKey, currentScopeName);
257
257
@@ -627,7 +627,7 @@ void IResolverContext.UseInstance(Type serviceType, object instance, IfAlreadyRe
627
627
var oldFactory = oldEntry as Factory;
628
628
if (oldFactory != null)
629
629
registry.DropFactoryCache(oldFactory, serviceType);
630
- else
630
+ else
631
631
((FactoriesEntry)oldEntry).Factories.Enumerate().ToArray()
632
632
.DoPer(x => registry.DropFactoryCache(x.Value, serviceType, serviceKey));
633
633
}
@@ -701,7 +701,7 @@ public IContainer With(Rules rules, IScopeContext scopeContext, RegistrySharing
701
701
/// <param name="ignoreInsteadOfThrow">(optional) Controls what to do with the next registration: ignore or throw exception.
702
702
/// Throws exception by default.</param>
703
703
public IContainer WithNoMoreRegistrationAllowed(bool ignoreInsteadOfThrow = false) =>
704
- new Container(Rules,
704
+ new Container(Rules,
705
705
Ref.Of(_registry.Value.WithNoMoreRegistrationAllowed(ignoreInsteadOfThrow)),
706
706
_singletonScope, _scopeContext, _ownCurrentScope,
707
707
_disposed, _disposeStackTrace, _parent, _root);
@@ -773,7 +773,7 @@ Factory IContainer.GetServiceFactoryOrDefault(Request request)
773
773
Type serviceType;
774
774
var requiredServiceType = request.RequiredServiceType;
775
775
if (requiredServiceType != null && requiredServiceType.IsOpenGeneric())
776
- serviceType = requiredServiceType;
776
+ serviceType = requiredServiceType;
777
777
else
778
778
{
779
779
// 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)
826
826
if (matchedFactories.Length == 1)
827
827
{
828
828
// 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)
830
830
request.ChangeServiceKey(matchedFactories[0].Key);
831
831
832
832
return matchedFactories[0].Value;
@@ -919,7 +919,7 @@ Expr IContainer.GetDecoratorExpressionOrDefault(Request request)
919
919
920
920
var arrayElementType = request.ServiceType.GetArrayElementTypeOrNull();
921
921
if (arrayElementType != null)
922
- request = request.WithChangedServiceInfo(x =>
922
+ request = request.WithChangedServiceInfo(x =>
923
923
x.With(typeof(IEnumerable<>).MakeGenericType(arrayElementType)));
924
924
925
925
var container = request.Container;
@@ -1176,7 +1176,7 @@ private KV<object, Factory>[] GetRegisteredServiceFactoriesOrNull(Type serviceTy
1176
1176
return null;
1177
1177
1178
1178
var factory = entry as Factory;
1179
- return factory != null
1179
+ return factory != null
1180
1180
? new KV<object, Factory>(DefaultKey.Value, factory).One()
1181
1181
: ((FactoriesEntry)entry).Factories.Enumerate().ToArray();
1182
1182
}
@@ -1402,13 +1402,18 @@ private Factory GetWrapperFactoryOrDefault(Request request)
1402
1402
return factory;
1403
1403
}
1404
1404
1405
+ internal void SetScopedProvider(IServiceProvider serviceProvider)
1406
+ {
1407
+ _scopedProvider = serviceProvider;
1408
+ }
1409
+
1405
1410
#endregion
1406
1411
1407
1412
#region Implementation
1408
1413
1409
1414
private int _disposed;
1410
1415
private StackTrace _disposeStackTrace;
1411
-
1416
+ private IServiceProvider _scopedProvider;
1412
1417
internal readonly Ref<Registry> _registry;
1413
1418
1414
1419
private readonly IScope _singletonScope;
@@ -1422,6 +1427,8 @@ private Factory GetWrapperFactoryOrDefault(Request request)
1422
1427
1423
1428
internal bool PreferInterpretation => _preferInterpretation;
1424
1429
1430
+ public IServiceProvider ScopedServiceProvider => _scopedProvider;
1431
+
1425
1432
internal sealed class InstanceFactory : Factory
1426
1433
{
1427
1434
public override Type ImplementationType { get; }
@@ -1791,14 +1798,14 @@ public Registry Unregister(FactoryType factoryType, Type serviceType, object ser
1791
1798
Factory removedWrapper = null;
1792
1799
var registry = WithWrappers(Wrappers.Update(serviceType, null, (factory, _null) =>
1793
1800
{
1794
- if (factory != null && condition != null && !condition(factory))
1801
+ if (factory != null && condition != null && !condition(factory))
1795
1802
return factory;
1796
1803
removedWrapper = factory;
1797
1804
return null;
1798
1805
1799
1806
}));
1800
1807
1801
- if (removedWrapper == null)
1808
+ if (removedWrapper == null)
1802
1809
return this;
1803
1810
registry.DropFactoryCache(removedWrapper, serviceType);
1804
1811
return registry;
@@ -1811,7 +1818,7 @@ public Registry Unregister(FactoryType factoryType, Type serviceType, object ser
1811
1818
return removedDecorators == factories ? null : factories.Except(removedDecorators).ToArray();
1812
1819
}));
1813
1820
1814
- if (removedDecorators.IsNullOrEmpty())
1821
+ if (removedDecorators.IsNullOrEmpty())
1815
1822
return this;
1816
1823
1817
1824
foreach (var removedDecorator in removedDecorators)
@@ -1908,7 +1915,7 @@ private Registry UnregisterServiceFactory(Type serviceType, object serviceKey =
1908
1915
1909
1916
internal void DropFactoryCache(Factory factory, Type serviceType, object serviceKey = null)
1910
1917
{
1911
- if (!DefaultFactoryDelegateCache.Value.IsEmpty ||
1918
+ if (!DefaultFactoryDelegateCache.Value.IsEmpty ||
1912
1919
!KeyedFactoryDelegateCache.Value.IsEmpty)
1913
1920
{
1914
1921
if (factory.FactoryGenerator == null)
@@ -1943,7 +1950,7 @@ private Container(Rules rules, Ref<Registry> registry, IScope singletonScope,
1943
1950
_registry = registry;
1944
1951
1945
1952
_singletonScope = singletonScope;
1946
-
1953
+
1947
1954
_scopeContext = scopeContext;
1948
1955
1949
1956
if (_scopeContext == null && !FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagEnableEnhancedScopes))
@@ -2000,7 +2007,7 @@ public override bool Equals(object obj)
2000
2007
public override int GetHashCode() => ImTools.HashCode.Combine(RequiredServiceType, ServiceKey);
2001
2008
2002
2009
/// <inheritdoc />
2003
- public Expr ToExpression(Func<object, Expr> fallbackConverter) =>
2010
+ public Expr ToExpression(Func<object, Expr> fallbackConverter) =>
2004
2011
New(_ctor, Constant(RequiredServiceType, typeof(Type)), fallbackConverter(ServiceKey));
2005
2012
2006
2013
private static readonly ConstructorInfo _ctor = typeof(OpenGenericTypeKey).SingleConstructor();
@@ -3762,7 +3769,7 @@ public static FactoryMethodSelector Constructor(bool mostResolvable = false, boo
3762
3769
3763
3770
// First the check for normal resolution without Func<a, b, c>
3764
3771
if (!request.IsWrappedInFuncWithArgs())
3765
- return Of(ctorsWithMaxParamsFirst.FindFirst(x =>
3772
+ return Of(ctorsWithMaxParamsFirst.FindFirst(x =>
3766
3773
x.GetParameters().FindFirst(p => !IsResolvableParameter(p, paramSelector, request)) == null)
3767
3774
.ThrowIfNull(Error.UnableToFindCtorWithAllResolvableArgs, request));
3768
3775
@@ -3832,7 +3839,7 @@ public static FactoryMethodSelector Constructor(bool mostResolvable = false, boo
3832
3839
};
3833
3840
3834
3841
/// <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 =>
3836
3843
request.ImplementationType.ThrowIfNull(Error.ImplTypeIsNotSpecifiedForAutoCtorSelection, request)
3837
3844
.GetConstructorOrNull(includeNonPublic, Empty<Type>())
3838
3845
?.Do(ctor => Of(ctor));
@@ -4055,12 +4062,12 @@ private static TypedMade<TService> FromExpression<TService>(
4055
4062
var hasCustomValue = false;
4056
4063
4057
4064
var parameterSelector = parameters.IsNullOrEmpty() ? null
4058
- : ComposeParameterSelectorFromArgs(ref hasCustomValue,
4065
+ : ComposeParameterSelectorFromArgs(ref hasCustomValue,
4059
4066
serviceReturningExpr, parameters, argExprs, argValues);
4060
4067
4061
4068
var propertiesAndFieldsSelector =
4062
4069
memberBindingExprs == null || memberBindingExprs.Count == 0 ? null
4063
- : ComposePropertiesAndFieldsSelector(ref hasCustomValue,
4070
+ : ComposePropertiesAndFieldsSelector(ref hasCustomValue,
4064
4071
serviceReturningExpr, memberBindingExprs, argValues);
4065
4072
4066
4073
return new TypedMade<TService>(factoryMethod, parameterSelector, propertiesAndFieldsSelector, hasCustomValue);
@@ -4089,7 +4096,7 @@ private Made(FactoryMethodSelector factoryMethod = null, ParameterSelector param
4089
4096
}
4090
4097
4091
4098
private static ParameterSelector ComposeParameterSelectorFromArgs(ref bool hasCustomValue,
4092
- Expression wholeServiceExpr, ParameterInfo[] paramInfos, IList<Expression> argExprs,
4099
+ Expression wholeServiceExpr, ParameterInfo[] paramInfos, IList<Expression> argExprs,
4093
4100
params Func<Request, object>[] argValues)
4094
4101
{
4095
4102
var paramSelector = DryIoc.Parameters.Of;
@@ -4174,7 +4181,7 @@ private static PropertiesAndFieldsSelector ComposePropertiesAndFieldsSelector(re
4174
4181
}
4175
4182
4176
4183
private static Func<Request, object> GetArgCustomValueProvider(
4177
- Expression wholeServiceExpr, MethodCallExpression methodCallExpr, Func<Request, object>[] argValues)
4184
+ Expression wholeServiceExpr, MethodCallExpression methodCallExpr, Func<Request, object>[] argValues)
4178
4185
{
4179
4186
Throw.If(argValues.IsNullOrEmpty(), Error.ArgValueIndexIsProvidedButNoArgValues, wholeServiceExpr);
4180
4187
@@ -4925,7 +4932,7 @@ private static void PopulateDependencyResolutionCallExpressions(Request request)
4925
4932
if (factoryExpr == null)
4926
4933
return;
4927
4934
4928
- request.Container.Rules.DependencyResolutionCallExprs.Swap(x =>
4935
+ request.Container.Rules.DependencyResolutionCallExprs.Swap(x =>
4929
4936
x.AddOrUpdate(request, factoryExpr
4930
4937
#if FEC_EXPRESSION_INFO
4931
4938
.ToExpression()
@@ -5383,7 +5390,7 @@ public override IServiceInfo Create(Type serviceType, ServiceDetails details) =>
5383
5390
5384
5391
public override void SetValue(object holder, object value) => _property.SetValue(holder, value, null);
5385
5392
5386
- public override string ToString() =>
5393
+ public override string ToString() =>
5387
5394
new StringBuilder().Print(this).Append(" as property ").Print(_property.Name, "\"").ToString();
5388
5395
5389
5396
private readonly PropertyInfo _property;
@@ -5409,7 +5416,7 @@ private class Field : PropertyOrFieldServiceInfo
5409
5416
{
5410
5417
public override Type ServiceType => _field.FieldType;
5411
5418
5412
- public override IServiceInfo Create(Type serviceType, ServiceDetails details) =>
5419
+ public override IServiceInfo Create(Type serviceType, ServiceDetails details) =>
5413
5420
serviceType == null ? new WithDetails(_field, details) : new TypeWithDetails(_field, serviceType, details);
5414
5421
5415
5422
public override MemberInfo Member => _field;
@@ -5630,7 +5637,7 @@ public Request Parent
5630
5637
public Type ServiceType => _serviceInfo.ServiceType;
5631
5638
5632
5639
/// <summary>Compatible required or service type.</summary>
5633
- public Type GetActualServiceType() =>
5640
+ public Type GetActualServiceType() =>
5634
5641
_actualServiceType ?? (_actualServiceType = _serviceInfo.GetActualServiceType());
5635
5642
5636
5643
private Type _actualServiceType; // saving result once
@@ -5672,8 +5679,8 @@ public Request Push(IServiceInfo info, RequestFlags additionalFlags = DefaultFla
5672
5679
5673
5680
/// <summary>Composes service description into <see cref="IServiceInfo"/> and Pushes the new request.</summary>
5674
5681
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),
5677
5684
requiredServiceType, ifUnresolved, serviceKey), flags);
5678
5685
5679
5686
#region Used in generated expression
@@ -5776,7 +5783,7 @@ public Request WithResolvedFactory(Factory factory,
5776
5783
}
5777
5784
5778
5785
// checking the service types only cause wrapper and decorators may be used multiple times
5779
- if (!skipRecursiveDependencyCheck &&
5786
+ if (!skipRecursiveDependencyCheck &&
5780
5787
factory.FactoryType == FactoryType.Service &&
5781
5788
HasRecursiveParent(factory.FactoryID))
5782
5789
Throw.It(Error.RecursiveDependencyDetected, Print(factory.FactoryID));
@@ -6529,7 +6536,7 @@ public virtual Expr GetExpressionOrDefault(Request request)
6529
6536
!request.IsResolutionCall && // preventing recursion
6530
6537
(Setup.AsResolutionCall || Setup.UseParentReuse || request.ShouldSplitObjectGraph()) &&
6531
6538
request.GetActualServiceType() != typeof(void)))
6532
- return Resolver.CreateResolutionExpression(request, Setup.OpenResolutionScope);
6539
+ return Resolver.CreateResolutionExpression(request, Setup.OpenResolutionScope);
6533
6540
6534
6541
// First look for decorators if it is not already a decorator
6535
6542
if (FactoryType != FactoryType.Decorator)
@@ -7083,14 +7090,14 @@ public override Expr CreateExpressionOrDefault(Request request)
7083
7090
var paramExpr = paramFactory?.GetExpressionOrDefault(paramRequest);
7084
7091
if (paramExpr == null ||
7085
7092
// 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 &&
7087
7094
paramExpr.NodeType == ExpressionType.NewArrayInit && ((NewArrayExpr)paramExpr).Expressions.Count == 0)
7088
7095
{
7089
7096
// Check if parameter dependency itself (without propagated parent details)
7090
7097
// does not allow default, then stop checking the rest of parameters.
7091
7098
if (paramInfo.Details.IfUnresolved == IfUnresolved.Throw)
7092
7099
return null;
7093
-
7100
+
7094
7101
var defaultValue = paramInfo.Details.DefaultValue;
7095
7102
paramExpr = defaultValue != null
7096
7103
? container.GetConstantExpression(defaultValue)
@@ -7247,10 +7254,10 @@ public Factory GetGeneratedFactory(Request request, bool ifErrorReturnDefault =
7247
7254
7248
7255
if (implType != null)
7249
7256
{
7250
- implType = implType.IsGenericParameter
7257
+ implType = implType.IsGenericParameter
7251
7258
? closedTypeArgs[0]
7252
7259
: Throw.IfThrows<ArgumentException, Type>(
7253
- () => implType.MakeGenericType(closedTypeArgs),
7260
+ () => implType.MakeGenericType(closedTypeArgs),
7254
7261
!ifErrorReturnDefault && request.IfUnresolved == IfUnresolved.Throw,
7255
7262
Error.NoMatchedGenericParamConstraints, implType, request);
7256
7263
if (implType == null)
@@ -7479,7 +7486,7 @@ private static void MatchOpenGenericConstraints(Type[] implTypeParams, Type[] im
7479
7486
continue; // skip yet unknown type arg
7480
7487
7481
7488
var implTypeParamConstraints = implTypeParams[i].GetGenericParamConstraints();
7482
- if (implTypeParamConstraints.IsNullOrEmpty())
7489
+ if (implTypeParamConstraints.IsNullOrEmpty())
7483
7490
continue; // skip case with no constraints
7484
7491
7485
7492
// match type parameters inside constraint
@@ -7843,7 +7850,7 @@ private object TryGetOrAdd(ImMap<object> items, int id, CreateScopedValue create
7843
7850
lock (_locker)
7844
7851
{
7845
7852
// 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))
7847
7854
return item;
7848
7855
7849
7856
item = createValue();
@@ -8067,7 +8074,7 @@ public Expr Apply(Request request, Expr serviceFactoryExpr) =>
8067
8074
Constant(request.FactoryID), Lambda<CreateScopedValue>(serviceFactoryExpr),
8068
8075
Constant(request.Factory.Setup.DisposalOrder));
8069
8076
8070
- private static readonly Lazy<Expr> _singletonReuseExpr = Lazy.Of<Expr>(() =>
8077
+ private static readonly Lazy<Expr> _singletonReuseExpr = Lazy.Of<Expr>(() =>
8071
8078
Field(null, typeof(Reuse).Field(nameof(Reuse.Singleton))));
8072
8079
8073
8080
/// <inheritdoc />
@@ -8268,11 +8275,11 @@ private ResolutionScopeName(Type serviceType, object serviceKey)
8268
8275
public bool Match(object scopeName)
8269
8276
{
8270
8277
var name = scopeName as ResolutionScopeName;
8271
- return name != null &&
8278
+ return name != null &&
8272
8279
(ServiceType == null ||
8273
8280
name.ServiceType.IsAssignableTo(ServiceType) ||
8274
- ServiceType.IsOpenGeneric() &&
8275
- name.ServiceType.GetGenericDefinitionOrNull().IsAssignableTo(ServiceType)) &&
8281
+ ServiceType.IsOpenGeneric() &&
8282
+ name.ServiceType.GetGenericDefinitionOrNull().IsAssignableTo(ServiceType)) &&
8276
8283
(ServiceKey == null || ServiceKey.Equals(name.ServiceKey));
8277
8284
}
8278
8285
@@ -8304,7 +8311,7 @@ public static class Reuse
8304
8311
8305
8312
/// <summary>Scoped to multiple names.</summary>
8306
8313
public static IReuse ScopedTo(params object[] names) =>
8307
- names.IsNullOrEmpty() ? Scoped
8314
+ names.IsNullOrEmpty() ? Scoped
8308
8315
: names.Length == 1 ? ScopedTo(names[0]) : new CurrentScopeReuse(CompositeScopeName.Of(names));
8309
8316
8310
8317
/// <summary>Same as InResolutionScopeOf. From now on will be the default name.</summary>
@@ -8535,6 +8542,8 @@ public enum RegistrySharing
8535
8542
/// <summary>Combines registrator and resolver roles, plus rules and scope management.</summary>
8536
8543
public interface IContainer : IRegistrator, IResolverContext
8537
8544
{
8545
+ IServiceProvider ScopedServiceProvider { get; }
8546
+
8538
8547
/// <summary>Rules for defining resolution/registration behavior throughout container.</summary>
8539
8548
Rules Rules { get; }
8540
8549
@@ -9538,7 +9547,7 @@ public static StringBuilder Print(this StringBuilder s, IEnumerable items,
9538
9547
/// <paramref name="getTypeName"/>Allows to specify if you want Name instead of FullName.</summary>
9539
9548
public static StringBuilder Print(this StringBuilder s, Type type, Func<Type, string> getTypeName = null)
9540
9549
{
9541
- if (type == null)
9550
+ if (type == null)
9542
9551
return s;
9543
9552
9544
9553
var isArray = type.IsArray;
0 commit comments