Skip to content

Commit

Permalink
Fix case with factory
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolayPianikov authored and NikolayPianikov committed Jul 10, 2020
1 parent 1a4383c commit 9ddd502
Show file tree
Hide file tree
Showing 22 changed files with 235 additions and 7 deletions.
8 changes: 8 additions & 0 deletions Docs/IoC_net40.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@
- [ContainerParameter](#P-IoC-IBuildContext-ContainerParameter 'IoC.IBuildContext.ContainerParameter')
- [Depth](#P-IoC-IBuildContext-Depth 'IoC.IBuildContext.Depth')
- [Key](#P-IoC-IBuildContext-Key 'IoC.IBuildContext.Key')
- [Parent](#P-IoC-IBuildContext-Parent 'IoC.IBuildContext.Parent')
- [AddParameter(parameterExpression)](#M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression- 'IoC.IBuildContext.AddParameter(System.Linq.Expressions.ParameterExpression)')
- [CreateChild(key,container)](#M-IoC-IBuildContext-CreateChild-IoC-Key,IoC-IContainer- 'IoC.IBuildContext.CreateChild(IoC.Key,IoC.IContainer)')
- [CreateExpression(defaultExpression)](#M-IoC-IBuildContext-CreateExpression-System-Linq-Expressions-Expression- 'IoC.IBuildContext.CreateExpression(System.Linq.Expressions.Expression)')
Expand Down Expand Up @@ -8125,6 +8126,13 @@ The depth of current context in the build tree.

The target key to build resolver.

<a name='P-IoC-IBuildContext-Parent'></a>
### Parent `property`

##### Summary

Provides a parent context or `null`.

<a name='M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression-'></a>
### AddParameter(parameterExpression) `method`

Expand Down
5 changes: 5 additions & 0 deletions Docs/IoC_net40.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Docs/IoC_net48.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@
- [ContainerParameter](#P-IoC-IBuildContext-ContainerParameter 'IoC.IBuildContext.ContainerParameter')
- [Depth](#P-IoC-IBuildContext-Depth 'IoC.IBuildContext.Depth')
- [Key](#P-IoC-IBuildContext-Key 'IoC.IBuildContext.Key')
- [Parent](#P-IoC-IBuildContext-Parent 'IoC.IBuildContext.Parent')
- [AddParameter(parameterExpression)](#M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression- 'IoC.IBuildContext.AddParameter(System.Linq.Expressions.ParameterExpression)')
- [CreateChild(key,container)](#M-IoC-IBuildContext-CreateChild-IoC-Key,IoC-IContainer- 'IoC.IBuildContext.CreateChild(IoC.Key,IoC.IContainer)')
- [CreateExpression(defaultExpression)](#M-IoC-IBuildContext-CreateExpression-System-Linq-Expressions-Expression- 'IoC.IBuildContext.CreateExpression(System.Linq.Expressions.Expression)')
Expand Down Expand Up @@ -8125,6 +8126,13 @@ The depth of current context in the build tree.

The target key to build resolver.

<a name='P-IoC-IBuildContext-Parent'></a>
### Parent `property`

##### Summary

Provides a parent context or `null`.

<a name='M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression-'></a>
### AddParameter(parameterExpression) `method`

Expand Down
5 changes: 5 additions & 0 deletions Docs/IoC_net48.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Docs/IoC_net5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@
- [ContainerParameter](#P-IoC-IBuildContext-ContainerParameter 'IoC.IBuildContext.ContainerParameter')
- [Depth](#P-IoC-IBuildContext-Depth 'IoC.IBuildContext.Depth')
- [Key](#P-IoC-IBuildContext-Key 'IoC.IBuildContext.Key')
- [Parent](#P-IoC-IBuildContext-Parent 'IoC.IBuildContext.Parent')
- [AddParameter(parameterExpression)](#M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression- 'IoC.IBuildContext.AddParameter(System.Linq.Expressions.ParameterExpression)')
- [CreateChild(key,container)](#M-IoC-IBuildContext-CreateChild-IoC-Key,IoC-IContainer- 'IoC.IBuildContext.CreateChild(IoC.Key,IoC.IContainer)')
- [CreateExpression(defaultExpression)](#M-IoC-IBuildContext-CreateExpression-System-Linq-Expressions-Expression- 'IoC.IBuildContext.CreateExpression(System.Linq.Expressions.Expression)')
Expand Down Expand Up @@ -8125,6 +8126,13 @@ The depth of current context in the build tree.

The target key to build resolver.

<a name='P-IoC-IBuildContext-Parent'></a>
### Parent `property`

##### Summary

Provides a parent context or `null`.

<a name='M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression-'></a>
### AddParameter(parameterExpression) `method`

Expand Down
5 changes: 5 additions & 0 deletions Docs/IoC_net5.0.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Docs/IoC_netcoreapp1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@
- [ContainerParameter](#P-IoC-IBuildContext-ContainerParameter 'IoC.IBuildContext.ContainerParameter')
- [Depth](#P-IoC-IBuildContext-Depth 'IoC.IBuildContext.Depth')
- [Key](#P-IoC-IBuildContext-Key 'IoC.IBuildContext.Key')
- [Parent](#P-IoC-IBuildContext-Parent 'IoC.IBuildContext.Parent')
- [AddParameter(parameterExpression)](#M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression- 'IoC.IBuildContext.AddParameter(System.Linq.Expressions.ParameterExpression)')
- [CreateChild(key,container)](#M-IoC-IBuildContext-CreateChild-IoC-Key,IoC-IContainer- 'IoC.IBuildContext.CreateChild(IoC.Key,IoC.IContainer)')
- [CreateExpression(defaultExpression)](#M-IoC-IBuildContext-CreateExpression-System-Linq-Expressions-Expression- 'IoC.IBuildContext.CreateExpression(System.Linq.Expressions.Expression)')
Expand Down Expand Up @@ -8089,6 +8090,13 @@ The depth of current context in the build tree.

The target key to build resolver.

<a name='P-IoC-IBuildContext-Parent'></a>
### Parent `property`

##### Summary

Provides a parent context or `null`.

<a name='M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression-'></a>
### AddParameter(parameterExpression) `method`

Expand Down
5 changes: 5 additions & 0 deletions Docs/IoC_netcoreapp1.0.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Docs/IoC_netcoreapp2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@
- [ContainerParameter](#P-IoC-IBuildContext-ContainerParameter 'IoC.IBuildContext.ContainerParameter')
- [Depth](#P-IoC-IBuildContext-Depth 'IoC.IBuildContext.Depth')
- [Key](#P-IoC-IBuildContext-Key 'IoC.IBuildContext.Key')
- [Parent](#P-IoC-IBuildContext-Parent 'IoC.IBuildContext.Parent')
- [AddParameter(parameterExpression)](#M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression- 'IoC.IBuildContext.AddParameter(System.Linq.Expressions.ParameterExpression)')
- [CreateChild(key,container)](#M-IoC-IBuildContext-CreateChild-IoC-Key,IoC-IContainer- 'IoC.IBuildContext.CreateChild(IoC.Key,IoC.IContainer)')
- [CreateExpression(defaultExpression)](#M-IoC-IBuildContext-CreateExpression-System-Linq-Expressions-Expression- 'IoC.IBuildContext.CreateExpression(System.Linq.Expressions.Expression)')
Expand Down Expand Up @@ -8125,6 +8126,13 @@ The depth of current context in the build tree.

The target key to build resolver.

<a name='P-IoC-IBuildContext-Parent'></a>
### Parent `property`

##### Summary

Provides a parent context or `null`.

<a name='M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression-'></a>
### AddParameter(parameterExpression) `method`

Expand Down
5 changes: 5 additions & 0 deletions Docs/IoC_netcoreapp2.0.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Docs/IoC_netcoreapp3.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@
- [ContainerParameter](#P-IoC-IBuildContext-ContainerParameter 'IoC.IBuildContext.ContainerParameter')
- [Depth](#P-IoC-IBuildContext-Depth 'IoC.IBuildContext.Depth')
- [Key](#P-IoC-IBuildContext-Key 'IoC.IBuildContext.Key')
- [Parent](#P-IoC-IBuildContext-Parent 'IoC.IBuildContext.Parent')
- [AddParameter(parameterExpression)](#M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression- 'IoC.IBuildContext.AddParameter(System.Linq.Expressions.ParameterExpression)')
- [CreateChild(key,container)](#M-IoC-IBuildContext-CreateChild-IoC-Key,IoC-IContainer- 'IoC.IBuildContext.CreateChild(IoC.Key,IoC.IContainer)')
- [CreateExpression(defaultExpression)](#M-IoC-IBuildContext-CreateExpression-System-Linq-Expressions-Expression- 'IoC.IBuildContext.CreateExpression(System.Linq.Expressions.Expression)')
Expand Down Expand Up @@ -8125,6 +8126,13 @@ The depth of current context in the build tree.

The target key to build resolver.

<a name='P-IoC-IBuildContext-Parent'></a>
### Parent `property`

##### Summary

Provides a parent context or `null`.

<a name='M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression-'></a>
### AddParameter(parameterExpression) `method`

Expand Down
5 changes: 5 additions & 0 deletions Docs/IoC_netcoreapp3.1.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Docs/IoC_netstandard1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@
- [ContainerParameter](#P-IoC-IBuildContext-ContainerParameter 'IoC.IBuildContext.ContainerParameter')
- [Depth](#P-IoC-IBuildContext-Depth 'IoC.IBuildContext.Depth')
- [Key](#P-IoC-IBuildContext-Key 'IoC.IBuildContext.Key')
- [Parent](#P-IoC-IBuildContext-Parent 'IoC.IBuildContext.Parent')
- [AddParameter(parameterExpression)](#M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression- 'IoC.IBuildContext.AddParameter(System.Linq.Expressions.ParameterExpression)')
- [CreateChild(key,container)](#M-IoC-IBuildContext-CreateChild-IoC-Key,IoC-IContainer- 'IoC.IBuildContext.CreateChild(IoC.Key,IoC.IContainer)')
- [CreateExpression(defaultExpression)](#M-IoC-IBuildContext-CreateExpression-System-Linq-Expressions-Expression- 'IoC.IBuildContext.CreateExpression(System.Linq.Expressions.Expression)')
Expand Down Expand Up @@ -8089,6 +8090,13 @@ The depth of current context in the build tree.

The target key to build resolver.

<a name='P-IoC-IBuildContext-Parent'></a>
### Parent `property`

##### Summary

Provides a parent context or `null`.

<a name='M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression-'></a>
### AddParameter(parameterExpression) `method`

Expand Down
5 changes: 5 additions & 0 deletions Docs/IoC_netstandard1.0.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Docs/IoC_netstandard2.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@
- [ContainerParameter](#P-IoC-IBuildContext-ContainerParameter 'IoC.IBuildContext.ContainerParameter')
- [Depth](#P-IoC-IBuildContext-Depth 'IoC.IBuildContext.Depth')
- [Key](#P-IoC-IBuildContext-Key 'IoC.IBuildContext.Key')
- [Parent](#P-IoC-IBuildContext-Parent 'IoC.IBuildContext.Parent')
- [AddParameter(parameterExpression)](#M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression- 'IoC.IBuildContext.AddParameter(System.Linq.Expressions.ParameterExpression)')
- [CreateChild(key,container)](#M-IoC-IBuildContext-CreateChild-IoC-Key,IoC-IContainer- 'IoC.IBuildContext.CreateChild(IoC.Key,IoC.IContainer)')
- [CreateExpression(defaultExpression)](#M-IoC-IBuildContext-CreateExpression-System-Linq-Expressions-Expression- 'IoC.IBuildContext.CreateExpression(System.Linq.Expressions.Expression)')
Expand Down Expand Up @@ -8125,6 +8126,13 @@ The depth of current context in the build tree.

The target key to build resolver.

<a name='P-IoC-IBuildContext-Parent'></a>
### Parent `property`

##### Summary

Provides a parent context or `null`.

<a name='M-IoC-IBuildContext-AddParameter-System-Linq-Expressions-ParameterExpression-'></a>
### AddParameter(parameterExpression) `method`

Expand Down
5 changes: 5 additions & 0 deletions Docs/IoC_netstandard2.1.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 42 additions & 3 deletions IoC.Source/IoC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8131,6 +8131,11 @@ namespace IoC
[PublicAPI]
public interface IBuildContext
{
/// <summary>
/// Provides a parent context or <c>null</c>.
/// </summary>
[CanBeNull] IBuildContext Parent { get; }

/// <summary>
/// The target key to build resolver.
/// </summary>
Expand Down Expand Up @@ -9353,6 +9358,7 @@ namespace IoC.Features
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using Core;
using Lifetimes;
using static Core.FluentRegister;
Expand All @@ -9363,6 +9369,8 @@ namespace IoC.Features
[PublicAPI]
public sealed class FuncFeature : IConfiguration
{
[NotNull] private static readonly MethodInfo ResolveWithTagGenericMethodInfo = ((MethodCallExpression)((Expression<Func<object>>)(() => Resolve<object>(default(IContainer), default(Tag), default(object[])))).Body).Method.GetGenericMethodDefinition();

/// The default instance.
public static readonly IConfiguration Set = new FuncFeature();

Expand Down Expand Up @@ -9400,7 +9408,34 @@ public bool TryBuildExpression(IBuildContext buildContext, ILifetime lifetime, o
var instanceType = genericTypeArguments[paramsCount];
var key = new Key(instanceType, buildContext.Key.Tag);
var context = buildContext.CreateChild(key, buildContext.Container);
var instanceExpression = context.CreateExpression();
var curContext = buildContext.Parent;
var reentrancy = false;
while (curContext != null)
{
if (curContext.Key.Equals(buildContext.Key))
{
reentrancy = true;
break;
}

curContext = curContext.Parent;
}

Expression instanceExpression;
if (!reentrancy)
{
instanceExpression = context.CreateExpression();
}
else
{
instanceExpression = Expression.Call(
null,
ResolveWithTagGenericMethodInfo.MakeGenericMethod(instanceType),
buildContext.ContainerParameter,
Expression.Constant(buildContext.Key.Tag),
buildContext.ArgsParameter);
}

var parameters = new ParameterExpression[paramsCount];
var parametersArgs = new Expression[paramsCount];
for (var i = 0; i < paramsCount; i++)
Expand Down Expand Up @@ -9436,6 +9471,9 @@ public bool TryBuildExpression(IBuildContext buildContext, ILifetime lifetime, o
return false;
}
}

private static T Resolve<T>([NotNull] IContainer container, object tag, [NotNull][ItemCanBeNull] params object[] args)
=> container.GetResolver<T>(new Tag(tag))(container, args);
}
}

Expand Down Expand Up @@ -11526,7 +11564,6 @@ internal sealed class BuildContext : IBuildContext
[NotNull] private readonly IEnumerable<IBuilder> _builders;
private readonly IList<ParameterExpression> _parameters = new List<ParameterExpression>();
[NotNull] private readonly ICompiler _compiler;
[CanBeNull] internal readonly BuildContext Parent;
[NotNull] private readonly IDictionary<Type, Type> _typesMap;

internal BuildContext(
Expand All @@ -11552,6 +11589,8 @@ internal BuildContext(
_typesMap = parent == null ? new Dictionary<Type, Type>() : new Dictionary<Type, Type>(parent._typesMap);
}

public IBuildContext Parent { get; private set; }

public Key Key { get; }

public IContainer Container { get; }
Expand Down Expand Up @@ -11673,7 +11712,7 @@ private IBuildContext CreateInternal(Key key, IContainer container, bool forBuil
public override string ToString()
{
var path = new List<IBuildContext>();
var context = this;
IBuildContext context = this;
while (context != null)
{
path.Add(context);
Expand Down
Loading

0 comments on commit 9ddd502

Please sign in to comment.