From 8d6a76a96edf55203fc9e90e1727a4e3ddd347df Mon Sep 17 00:00:00 2001 From: Nikolay Pianikov Date: Thu, 18 Apr 2024 13:08:55 +0300 Subject: [PATCH] The Bind method without parameters should only add bindings to first-level abstractions for the type --- src/Pure.DI.Core/Core/BaseSymbolsProvider.cs | 2 +- .../Core/Code/VariablesBuilder.cs | 5 ++ .../GenericRootsTests.cs | 81 +++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/Pure.DI.Core/Core/BaseSymbolsProvider.cs b/src/Pure.DI.Core/Core/BaseSymbolsProvider.cs index 22e77e255..9ea697a84 100644 --- a/src/Pure.DI.Core/Core/BaseSymbolsProvider.cs +++ b/src/Pure.DI.Core/Core/BaseSymbolsProvider.cs @@ -14,7 +14,7 @@ public IEnumerable GetBaseSymbols(ITypeSymbol symbol, int deep = in while (true) { yield return symbol; - foreach (var type in symbol.AllInterfaces.SelectMany(i => GetBaseSymbols(i, deep))) + foreach (var type in symbol.Interfaces.SelectMany(i => GetBaseSymbols(i, deep))) { yield return type; } diff --git a/src/Pure.DI.Core/Core/Code/VariablesBuilder.cs b/src/Pure.DI.Core/Core/Code/VariablesBuilder.cs index e6cf491b7..9c8ab4fca 100644 --- a/src/Pure.DI.Core/Core/Code/VariablesBuilder.cs +++ b/src/Pure.DI.Core/Core/Code/VariablesBuilder.cs @@ -28,6 +28,11 @@ public Block Build( var stack = new Stack(currentBlock.Statements); while (stack.TryPop(out var currentStatement)) { + if (stack.Count > 0xffff) + { + throw new CompileErrorException($"Cyclic dependency has been found.", rootNode.Binding.Source.GetLocation(), LogId.ErrorCyclicDependency); + } + switch (currentStatement) { case Block block: diff --git a/tests/Pure.DI.IntegrationTests/GenericRootsTests.cs b/tests/Pure.DI.IntegrationTests/GenericRootsTests.cs index ad59243d9..6c4ed8965 100644 --- a/tests/Pure.DI.IntegrationTests/GenericRootsTests.cs +++ b/tests/Pure.DI.IntegrationTests/GenericRootsTests.cs @@ -549,4 +549,85 @@ public static void Main() result.Success.ShouldBeTrue(result); result.StdOut.ShouldBe(["2"], result); } + + [Fact] + public async Task ShouldSupportGenericRootWithTags() + { + // Given + + // When + var result = await """ +using System; +using System.Linq; +using Pure.DI; +using static Pure.DI.Lifetime; + +namespace Sample +{ + interface IRunner + { + T Run(T value); + } + + interface IPipeline : IRunner + { + } + + class Pipeline : IPipeline + { + private readonly IRunner[] _runners; + + public Pipeline(params IRunner[] runners) + { + _runners = runners; + } + + public T Run(T value) => + _runners.Aggregate( + value, + (current, handler) => handler.Run(current)); + } + + class Tracer: IRunner + { + public T Run(T value) + { + Console.WriteLine(value); + return value; + } + } + + class SquareRootCalculator: IRunner + { + public decimal Run(decimal value) => + value * value; + } + + internal partial class Composition + { + void Setup() + { + DI.Setup(nameof(Composition)) + .Bind(0).To>() + .Bind(1).To() + .Bind(2).To>() + .Bind().To>() + .Root>("Pipeline"); + } + } + + public class Program + { + public static void Main() + { + new Composition().Pipeline.Run(7); + } + } +} +""".RunAsync(new Options(LanguageVersion.CSharp9)); + + // Then + result.Success.ShouldBeTrue(result); + result.StdOut.ShouldBe(["7", "49"], result); + } } \ No newline at end of file