Skip to content

Commit bcff8da

Browse files
author
maximv
committed
wip: initial fix for #315; many @Perf todos added
1 parent 6f466ee commit bcff8da

3 files changed

+41
-9
lines changed

src/DryIoc/Container.cs

+12-8
Original file line numberDiff line numberDiff line change
@@ -3013,22 +3013,25 @@ i.Expression is ConstantExpression cd &&
30133013
return TryInterpret(r, f.Body, paramExprs, paramValues, parentArgs, useFec, out result);
30143014

30153015
#if !SUPPORTS_DELEGATE_METHOD
3016-
return false;
3016+
return false;
30173017
#else
3018-
if (!TryInterpret(r, delegateExpr, paramExprs, paramValues, parentArgs, useFec, out var delegateObj))
3018+
if (!TryInterpret(r, delegateExpr, paramExprs, paramValues, parentArgs, useFec, out var delegateObj)) // todo: @perf avoid calling the TryInterpret for the known constant of FactoryDelegate
30193019
return false;
30203020

30213021
var lambda = (Delegate)delegateObj;
3022-
var argExprs = invokeExpr.Arguments.ToListOrSelf();
3022+
var argExprs = invokeExpr.Arguments.ToListOrSelf(); // todo: @perf recognize the OneArgumentInvocationExpression
30233023
if (argExprs.Count == 0)
30243024
result = lambda.GetMethodInfo().Invoke(lambda.Target, ArrayTools.Empty<object>());
30253025
else
30263026
{
3027-
var args = new object[argExprs.Count];
3027+
var args = new object[argExprs.Count]; // todo: @perf avoid allocating for the single argument
30283028
for (var i = 0; i < args.Length; i++)
3029-
if (!TryInterpret(r, argExprs[i], paramExprs, paramValues, parentArgs, useFec, out args[i]))
3029+
if (!TryInterpret(r, argExprs[i], paramExprs, paramValues, parentArgs, useFec, out args[i])) // todo: @perf simplify for the single argument `r` of ResolverContext for FactoryDelegate
30303030
return false;
3031-
result = lambda.GetMethodInfo().Invoke(lambda.Target, args);
3031+
if (lambda is FactoryDelegate fd)
3032+
result = fd.Invoke((IResolverContext)args[0]);
3033+
else
3034+
result = lambda.GetMethodInfo().Invoke(lambda.Target, args);
30323035
}
30333036
return true;
30343037
#endif
@@ -3284,7 +3287,7 @@ private static bool TryInterpretMethodCall(IResolverContext r, Expression expr,
32843287
return true;
32853288
}
32863289

3287-
var callArgs = callExpr.Arguments.ToListOrSelf();
3290+
var callArgs = callExpr.Arguments.ToListOrSelf(); // todo: Check for the few arguments method call expression
32883291
var resolver = r;
32893292
if (!ReferenceEquals(callArgs[0], FactoryDelegateCompiler.ResolverContextParamExpr))
32903293
{
@@ -3310,7 +3313,7 @@ private static bool TryInterpretMethodCall(IResolverContext r, Expression expr,
33103313
{
33113314
if (!TryInterpret(resolver, callArgs[2], paramExprs, paramValues, parentArgs, useFec, out var service))
33123315
return false;
3313-
result = scope.TrackDisposable(service /* todo: what is with `disposalOrder`*/);
3316+
result = scope.TrackDisposable(service); // todo: what is with `disposalOrder`
33143317
}
33153318

33163319
return true;
@@ -11327,6 +11330,7 @@ object TryGetOrAddWithoutClosure(int id,
1132711330
IResolverContext resolveContext, Expression expr, bool useFec,
1132811331
Func<IResolverContext, Expression, bool, object> createValue, int disposalOrder = 0);
1132911332

11333+
// todo: @perf introduce the overload WithoutDisposalOrder
1133011334
/// <summary>Tracked item will be disposed with the scope.
1133111335
/// Smaller <paramref name="disposalOrder"/> will be disposed first.</summary>
1133211336
object TrackDisposable(object item, int disposalOrder = 0);
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace DryIoc.IssuesTests
44
{
5-
public class GIssue233_Add_RegisterDelegate_with_parameters_returning_object_for_the_requested_runtime_known_service_type
5+
public class GHIssue233_Add_RegisterDelegate_with_parameters_returning_object_for_the_requested_runtime_known_service_type
66
{
77
[Test]
88
public void Should_be_able_to_use_delegate_with_one_argument_returning_object()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using NUnit.Framework;
3+
4+
namespace DryIoc.IssuesTests
5+
{
6+
[TestFixture]
7+
public class GHIssue315_Combining_RegisterDelegate_with_TrackingDisposableTransients_rule_throws_TargetParameterCountException
8+
{
9+
[Test]
10+
public void Test()
11+
{
12+
var container = new Container(rules => rules.WithTrackingDisposableTransients());
13+
container.RegisterDelegate<Foo>(c => new Bar());
14+
var foo = container.Resolve<Foo>();
15+
16+
container.Dispose();
17+
Assert.IsTrue(container.IsDisposed);
18+
}
19+
20+
public class Foo : IDisposable
21+
{
22+
public bool IsDisposed;
23+
public void Dispose() => IsDisposed = true;
24+
}
25+
26+
public class Bar : Foo { }
27+
}
28+
}

0 commit comments

Comments
 (0)