From 2af8553d08b4986248bcc572281a0ef169876ca1 Mon Sep 17 00:00:00 2001 From: Nikolay Pianikov Date: Mon, 16 Dec 2024 20:34:54 +0300 Subject: [PATCH] Fix expressions in factories using typeof() as a tag --- src/Pure.DI.Core/Core/Code/FactoryRewriter.cs | 21 +---- .../Pure.DI.IntegrationTests/FactoryTests.cs | 94 ++++++++++++++++++- 2 files changed, 93 insertions(+), 22 deletions(-) diff --git a/src/Pure.DI.Core/Core/Code/FactoryRewriter.cs b/src/Pure.DI.Core/Core/Code/FactoryRewriter.cs index e8c733672..aefe3023e 100644 --- a/src/Pure.DI.Core/Core/Code/FactoryRewriter.cs +++ b/src/Pure.DI.Core/Core/Code/FactoryRewriter.cs @@ -244,26 +244,7 @@ private bool TryInitialize( && node is { Expression: IdentifierNameSyntax identifierName, Name.Identifier.Text: nameof(IContext.Tag) } && identifierName.Identifier.Text == factory.Source.Context.Identifier.Text) { - var token = SyntaxFactory.ParseToken(variable.Injection.Tag.ValueToString()); - if (token.IsKind(SyntaxKind.NumericLiteralToken)) - { - return SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, token); - } - - if (token.IsKind(SyntaxKind.CharacterLiteralToken)) - { - return SyntaxFactory.LiteralExpression(SyntaxKind.CharacterLiteralExpression, token); - } - - if (token.IsKind(SyntaxKind.StringLiteralToken)) - { - return SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, token); - } - - if (token.IsKind(SyntaxKind.NullKeyword)) - { - return SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, token); - } + return SyntaxFactory.ParseExpression(variable.Injection.Tag.ValueToString()); } return base.VisitMemberAccessExpression(node); diff --git a/tests/Pure.DI.IntegrationTests/FactoryTests.cs b/tests/Pure.DI.IntegrationTests/FactoryTests.cs index 1cd0c3b85..61212e831 100644 --- a/tests/Pure.DI.IntegrationTests/FactoryTests.cs +++ b/tests/Pure.DI.IntegrationTests/FactoryTests.cs @@ -652,8 +652,8 @@ public class Program { public static void Main() { - var composition = new Composition(); - var service = composition.Service; + var composition = new Composition(); + var service = composition.Service; } } } @@ -663,6 +663,96 @@ public static void Main() result.Success.ShouldBeTrue(result); result.StdOut.ShouldBe(["Created"], result); } + + [Theory] + [InlineData("123", "ctx.Tag", "123")] + [InlineData("\"123\"", "ctx.Tag", "123")] + [InlineData("'1'", "((char)ctx.Tag) + 1", "50")] + [InlineData("123", "(object)ctx.Tag", "123")] + [InlineData("123", "int.Parse(ctx.Tag.ToString() ?? \"\")", "123")] + [InlineData("123", "dependency.GetInt((int)ctx.Tag)", "123")] + [InlineData("123", "((int)ctx.Tag) * 2", "246")] + [InlineData("123", "dependency.GetInt((int)ctx.Tag) * 2", "246")] + [InlineData("typeof(int)", "ctx.Tag", "System.Int32")] + public async Task ShouldSupportFactoryWhenUsingParentTag(string tag, string tagExpression, string output) + { + // Given + + // When + var result = await """ + using System; + using Pure.DI; + + namespace Sample + { + interface IDependency + { + int GetInt(int val); + } + + class Dependency: IDependency + { + public int GetInt(int val) => val; + } + + interface IService + { + IDependency Dep { get; } + } + + class Service: IService + { + public Service(IDependency dep) + { + Dep = dep; + Console.WriteLine("Created"); + } + + public IDependency Dep { get; } + } + + internal partial class Composition + { + private partial T OnDependencyInjection(in T value, object? tag, Lifetime lifetime) + { + return value; + } + } + + static class Setup + { + private static void SetupComposition() + { + // OnDependencyInjection = On + DI.Setup("Composition") + .Bind(#tag#).To(ctx => new Dependency()) + .Bind(#tag#).To(ctx => { + ctx.Inject(ctx.Tag, out var dependency); + Console.WriteLine(#tagExpression#); + return new Service(dependency); + }) + .Root("Service", #tag#); + } + } + + public class Program + { + public static void Main() + { + var composition = new Composition(); + var service = composition.Service; + } + } + } + """ + .Replace("#tagExpression#", tagExpression) + .Replace("#tag#", tag) + .RunAsync(new Options(LanguageVersion.CSharp9)); + + // Then + result.Success.ShouldBeTrue(result); + result.StdOut.ShouldBe([output, "Created"], result); + } [Fact] public async Task ShouldSupportFactoryWithInjectInFunc()