Skip to content

Commit

Permalink
fixed: #434
Browse files Browse the repository at this point in the history
  • Loading branch information
dadhi committed Oct 30, 2021
1 parent 323fe98 commit e94a67f
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 15 deletions.
35 changes: 20 additions & 15 deletions src/DryIoc/Container.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2006,7 +2006,9 @@ public override FactoryDelegate GetDelegateOrDefault(Request request)
return decoratedExpr.CompileToFactoryDelegate(request.Rules.UseFastExpressionCompiler, request.Rules.UseInterpretation);
}

return GetInstanceFromScopeChainOrSingletons;
return request.IfUnresolved == IfUnresolved.Throw
? GetInstanceFromScopeChainOrSingletons
: GetInstanceFromScopeChainOrSingletonsOrDefault;
}

/// <summary>Called for Injection as dependency.</summary>
Expand All @@ -2020,32 +2022,35 @@ public override Expression GetExpressionOrDefault(Request request)
public override Expression CreateExpressionOrDefault(Request request) =>
Resolver.CreateResolutionExpression(request);

#region Implementation

private object GetInstanceFromScopeChainOrSingletons(IResolverContext r)
{
for (var scope = r.CurrentScope; scope != null; scope = scope.Parent)
for (var s = r.CurrentScope; s != null; s = s.Parent)
{
var result = GetAndUnwrapOrDefault(scope, FactoryID);
var result = GetAndUnwrapOrDefault(s, FactoryID);
if (result != null)
return result;
}

var instance = GetAndUnwrapOrDefault(r.SingletonScope, FactoryID);
return instance.ThrowIfNull(Error.UnableToFindSingletonInstance);
return GetAndUnwrapOrDefault(r.SingletonScope, FactoryID).ThrowIfNull(Error.UnableToFindSingletonInstance);
}

private static object GetAndUnwrapOrDefault(IScope scope, int factoryId)
private object GetInstanceFromScopeChainOrSingletonsOrDefault(IResolverContext r)
{
object value;
if (!scope.TryGet(out value, factoryId))
return null;
return (value as WeakReference)?.Target.ThrowIfNull(Error.WeakRefReuseWrapperGCed)
?? (value as HiddenDisposable)?.Value
?? value;
for (var s = r.CurrentScope; s != null; s = s.Parent)
{
var result = GetAndUnwrapOrDefault(s, FactoryID);
if (result != null)
return result;
}

return GetAndUnwrapOrDefault(r.SingletonScope, FactoryID);
}

#endregion
private static object GetAndUnwrapOrDefault(IScope scope, int factoryId) =>
!scope.TryGet(out var value, factoryId) ? null :
(value as WeakReference)?.Target.ThrowIfNull(Error.WeakRefReuseWrapperGCed)
?? (value as HiddenDisposable)?.Value
?? value;
}

internal sealed class Registry
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using NUnit.Framework;

namespace DryIoc.IssuesTests
{
[TestFixture]
public class GHIssue434_ReturnDefaultIfNotRegistered_is_not_respected_between_scopes
{
[Test]
public void Test_UseInstance()
{
var container = new Container();

using (var scope = container.OpenScope())
{
var foo = scope.Resolve<Foo>(IfUnresolved.ReturnDefaultIfNotRegistered); // Does not throw
scope.UseInstance<Foo>(new Foo()); // Do a registration within the scope
}

using (var scope = container.OpenScope())
{
var foo = scope.Resolve<Foo>(IfUnresolved.ReturnDefaultIfNotRegistered);
Assert.IsNull(foo);
}
}

[Test]
public void Test_Use()
{
var container = new Container();

using (var scope = container.OpenScope())
{
var foo = scope.Resolve<Foo>(IfUnresolved.ReturnDefaultIfNotRegistered); // Does not throw
scope.Use<Foo>(new Foo()); // Do a registration within the scope
}

using (var scope = container.OpenScope())
{
var foo = scope.Resolve<Foo>(IfUnresolved.ReturnDefaultIfNotRegistered);
Assert.IsNull(foo);

var ex = Assert.Throws<ContainerException>(() =>
scope.Resolve<Foo>());
Assert.AreEqual(Error.NameOf(Error.UnableToResolveUnknownService), ex.ErrorName);

foo = scope.Resolve<Foo>(IfUnresolved.ReturnDefault);
Assert.IsNull(foo);
}
}

class Foo
{
}
}
}

0 comments on commit e94a67f

Please sign in to comment.