Skip to content

Commit

Permalink
fixed: #446
Browse files Browse the repository at this point in the history
  • Loading branch information
dadhi committed Jan 6, 2022
1 parent 2ecc93b commit 1fc25ba
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
20 changes: 17 additions & 3 deletions src/DryIoc/Container.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5913,7 +5913,7 @@ public static UnknownServiceResolver AutoResolveConcreteTypeRule(Func<Request, b
return null;

var factory = new ReflectionFactory(concreteType,
made: DryIoc.FactoryMethod.ConstructorWithResolvableArgumentsIncludingNonPublic);
made: DryIoc.FactoryMethod.ConstructorWithResolvableArgumentsIncludingNonPublicWithoutSameTypeParam);

// to enable fallback to other rules if unresolved try to resolve expression first and return null
return factory.GetExpressionOrDefault(request.WithIfUnresolved(IfUnresolved.ReturnDefault)) != null ? factory : null;
Expand Down Expand Up @@ -5947,7 +5947,7 @@ public static DynamicRegistrationProvider ConcreteTypeDynamicRegistrations(

// the condition checks that factory is resolvable
factory = new ReflectionFactory(implType, reuse,
DryIoc.FactoryMethod.ConstructorWithResolvableArgumentsIncludingNonPublic,
DryIoc.FactoryMethod.ConstructorWithResolvableArgumentsIncludingNonPublicWithoutSameTypeParam,
Setup.With(condition: req => factory?.GetExpressionOrDefault(req.WithIfUnresolved(IfUnresolved.ReturnDefault)) != null));

return factory;
Expand Down Expand Up @@ -6546,12 +6546,20 @@ private static FactoryMethod Constructor(Request request, bool includeNonPublic)
return ctors.Length == 1 ? new FactoryMethod(ctors[0]) : null;
}

private static FactoryMethod MostResolvableConstructor(Request request, bool includeNonPublic)
private static FactoryMethod MostResolvableConstructor(Request request, bool includeNonPublic,
Func<Type, ParameterInfo[], bool> condition = null)
{
var implType = request.ImplementationType.ThrowIfNull(Error.ImplTypeIsNotSpecifiedForAutoCtorSelection, request);
// todo: @perf we can inline this because we do double checking on the number of constructors
var ctors = implType.Constructors(includeNonPublic).ToArrayOrSelf();

var ctorCount = ctors.Length;
if (ctorCount != 0 && condition != null)
{
ctors = ctors.Match(condition, (cond, c) => cond(c.DeclaringType, c.GetParameters()));
ctorCount = ctors.Length;
}

if (ctorCount == 0)
return null;

Expand Down Expand Up @@ -6708,6 +6716,12 @@ public static FactoryMethodSelector DefaultConstructor(bool includeNonPublic = f
public static readonly FactoryMethodSelector ConstructorWithResolvableArgumentsIncludingNonPublic =
Constructor(mostResolvable: true, includeNonPublic: true);

/// <summary>Searches for a single constructor excluding the ones with the same implemengtation type as parameter.
/// Used by the AutoConcrete type resolution to avoid selection of recursive constructors like `Foo(Foo f)`</summary>
public static readonly FactoryMethodSelector ConstructorWithResolvableArgumentsIncludingNonPublicWithoutSameTypeParam =
request => MostResolvableConstructor(request, true,
(implType, ps) => ps.FindFirst(implType, (t, p) => t == p.ParameterType) == null);

/// <summary>Just creates a thingy from the constructor</summary>
public FactoryMethod(ConstructorInfo constructor) =>
ConstructorOrMethodOrMember = constructor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@ namespace DryIoc.IssuesTests
[TestFixture]
public class GHIssue446_Resolving_a_record_without_registration_causes_a_StackOverflowException
{
//[Test]
public void Test()
[Test]
public void Test1()
{
var container = new Container(Rules.Default.WithAutoConcreteTypeResolution());
//container.Register<Foo>();
container.Resolve<Foo>();
var foo = container.Resolve<Foo>();
Assert.IsInstanceOf<Foo>(foo);
}

[Test]
public void Test2()
{
var container = new Container(Rules.Default.WithConcreteTypeDynamicRegistrations());
var foo = container.Resolve<Foo>();
Assert.IsInstanceOf<Foo>(foo);
}

//record Foo;
Expand Down

0 comments on commit 1fc25ba

Please sign in to comment.