@@ -9893,10 +9893,7 @@ cacheEntry.Value.ScopeNameOrDependencyCount is Container.Registry.TransientDepen
9893
9893
9894
9894
// Next, lookup for the already created service in the singleton scope
9895
9895
Expression serviceExpr;
9896
- if (request.Reuse is SingletonReuse &&
9897
- request.Rules.EagerCachingSingletonForFasterAccess
9898
- // && !request.IsWrappedInFunc() -- see the Note below for the reasons why it is commented out
9899
- )
9896
+ if (request.Reuse is SingletonReuse && request.Rules.EagerCachingSingletonForFasterAccess)
9900
9897
{
9901
9898
// Then optimize for already resolved singleton object, otherwise goes normal ApplyReuse route
9902
9899
var id = request.FactoryType == FactoryType.Decorator
@@ -9913,16 +9910,22 @@ cacheEntry.Value.ScopeNameOrDependencyCount is Container.Registry.TransientDepen
9913
9910
//
9914
9911
// `class Singleton { public Singleton(Func<Singleton> fs) {} }`
9915
9912
//
9916
- // In this situation the `itemRef` will be creating but will stuck forever on the `WaitForItemIsSet` below.
9917
- // So the way-out here is to abondon the attempt to wait for the item and proceed to normal Expression creation.
9913
+ // In this situation the `itemRef` will stuck forever on the `WaitForItemIsSet` below.
9914
+ // So the way-out here is to abondon the attempt to wait for the item if we are not in the Func
9915
+ // and proceed to the normal Expression creation.
9918
9916
//
9917
+ if (itemRef.Value == Scope.NoItem)
9918
+ {
9919
+ if (!request.TracksTransientDisposable && !request.IsWrappedInFunc())
9920
+ Scope.WaitForItemIsSet(itemRef);
9921
+ }
9922
+
9919
9923
if (itemRef.Value != Scope.NoItem) // get the item if and only if it is already created
9920
9924
{
9921
9925
var singleton = itemRef.Value;
9922
- serviceExpr = singleton == null
9923
- ? Constant(null, request.GetActualServiceType()) // fixes #258
9924
- : Constant(singleton);
9925
-
9926
+ serviceExpr = singleton != null ? Constant(singleton)
9927
+ : Constant(null, request.GetActualServiceType()); // fixes #258
9928
+
9926
9929
if (Setup.WeaklyReferenced) // Unwrap WeakReference or HiddenDisposable in that order!
9927
9930
serviceExpr = Call(ThrowInGeneratedCode.WeakRefReuseWrapperGCedMethod,
9928
9931
Property(Convert(serviceExpr, typeof(WeakReference)), ThrowInGeneratedCode.WeakReferenceValueProperty));
@@ -10003,10 +10006,8 @@ protected virtual Expression ApplyReuse(Expression serviceExpr, Request request)
10003
10006
// This optimization eagerly creates singleton during the construction of object graph
10004
10007
// Singleton is created once and then is stred for the container lifetime (until Сontainer.SingletonScope is disposed).
10005
10008
// That's why we are always intepreting them even if `Rules.WithoutInterpretationForTheFirstResolution()` is set.
10006
- if (request.Reuse is SingletonReuse &&
10007
- request.Rules.EagerCachingSingletonForFasterAccess &&
10008
- !request.TracksTransientDisposable &&
10009
- !request.IsWrappedInFunc())
10009
+ if (request.Reuse is SingletonReuse && request.Rules.EagerCachingSingletonForFasterAccess &&
10010
+ !request.TracksTransientDisposable && !request.IsWrappedInFunc())
10010
10011
{
10011
10012
var container = request.Container;
10012
10013
var scope = (Scope)container.SingletonScope;
0 commit comments