From 37c55af1f8f1570ac0e9121b1a14e814f8103df9 Mon Sep 17 00:00:00 2001 From: Nikolay Pianikov Date: Tue, 20 Aug 2024 23:27:28 +0300 Subject: [PATCH] #69 Feature request: validate scopes - show error --- src/Pure.DI.Core/Core/LifetimesValidator.cs | 6 +++--- src/Pure.DI.Core/Core/LifetimesValidatorVisitor.cs | 6 +++--- src/Pure.DI.Core/Core/LogId.cs | 2 +- tests/Pure.DI.IntegrationTests/LifetimesTests.cs | 14 ++++++-------- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/Pure.DI.Core/Core/LifetimesValidator.cs b/src/Pure.DI.Core/Core/LifetimesValidator.cs index c6f882f50..3a229c83e 100644 --- a/src/Pure.DI.Core/Core/LifetimesValidator.cs +++ b/src/Pure.DI.Core/Core/LifetimesValidator.cs @@ -14,18 +14,18 @@ public bool Validate(DependencyGraph dependencyGraph) return false; } - var warnings = new HashSet(); + var errors = new HashSet(); var graph = dependencyGraph.Graph; foreach (var root in dependencyGraph.Roots) { pathsWalker.Walk( - warnings, + errors, graph, root.Value.Node, visitor, cancellationToken); } - return true; + return errors.Count == 0; } } \ No newline at end of file diff --git a/src/Pure.DI.Core/Core/LifetimesValidatorVisitor.cs b/src/Pure.DI.Core/Core/LifetimesValidatorVisitor.cs index c50442157..05ee630d3 100644 --- a/src/Pure.DI.Core/Core/LifetimesValidatorVisitor.cs +++ b/src/Pure.DI.Core/Core/LifetimesValidatorVisitor.cs @@ -23,9 +23,9 @@ public bool Visit(HashSet errors, in ImmutableArray path var dependencyNode = path[i]; if (!ValidateLifetimes(actualTargetLifetimeNode.Lifetime, dependencyNode.Lifetime)) { - if (errors.Add(new WarningKey(actualTargetLifetimeNode, dependencyNode))) + if (errors.Add(new ErrorKey(actualTargetLifetimeNode, dependencyNode))) { - logger.CompileWarning($"Type {actualTargetLifetimeNode.Type} with lifetime {actualTargetLifetimeNode.Lifetime} requires direct or transitive dependency injection of type {dependencyNode.Type} with lifetime {dependencyNode.Lifetime}, which can lead to data leakage and inconsistent behavior.", dependencyNode.Binding.Source.GetLocation(), LogId.WarningLifetimeDefect); + logger.CompileError($"Type {actualTargetLifetimeNode.Type} with lifetime {actualTargetLifetimeNode.Lifetime} requires direct or transitive dependency injectionion of type {dependencyNode.Type} with lifetime {dependencyNode.Lifetime}, which can lead to data leakage and inconsistent behavior.", dependencyNode.Binding.Source.GetLocation(), LogId.ErrorLifetimeDefect); } } @@ -42,5 +42,5 @@ private static bool ValidateLifetimes(Lifetime actualTargetLifetime, Lifetime de !(actualTargetLifetime == Lifetime.Singleton && dependencyLifetime == Lifetime.Scoped); [SuppressMessage("ReSharper", "NotAccessedPositionalProperty.Local")] - private record WarningKey(DependencyNode TargetNode, DependencyNode SourceNode); + private record ErrorKey(DependencyNode TargetNode, DependencyNode SourceNode); } \ No newline at end of file diff --git a/src/Pure.DI.Core/Core/LogId.cs b/src/Pure.DI.Core/Core/LogId.cs index 7921dd3f4..37828016b 100644 --- a/src/Pure.DI.Core/Core/LogId.cs +++ b/src/Pure.DI.Core/Core/LogId.cs @@ -8,6 +8,7 @@ internal static class LogId public const string ErrorCannotFindSetup = "DIE002"; public const string ErrorCyclicDependency = "DIE003"; public const string ErrorNotSupportedLanguageVersion = "DIE004"; + public const string ErrorLifetimeDefect = "DIW005"; public const string ErrorUnhandled = "DIE999"; // Warning @@ -15,7 +16,6 @@ internal static class LogId public const string WarningMetadataDefect = "DIW001"; public const string WarningRootArgInResolveMethod = "DIW002"; public const string WarningTypeArgInResolveMethod = "DIW003"; - public const string WarningLifetimeDefect = "DIW004"; // Info public const string InfoGenerationInterrupted = "DII000"; diff --git a/tests/Pure.DI.IntegrationTests/LifetimesTests.cs b/tests/Pure.DI.IntegrationTests/LifetimesTests.cs index 04889958c..3583371d7 100644 --- a/tests/Pure.DI.IntegrationTests/LifetimesTests.cs +++ b/tests/Pure.DI.IntegrationTests/LifetimesTests.cs @@ -2505,7 +2505,7 @@ public static void Main() } [Fact] - public async Task ShouldShowWarningWhenSingletonInjectsScoped() + public async Task ShouldShowErrorWhenSingletonInjectsScoped() { // Given @@ -2661,13 +2661,12 @@ public static void Main() // Then result.Success.ShouldBeFalse(result); - result.StdOut.ShouldBe(["True", "True", "True", "True", "True", "True", "True", "True", "True"], result); - result.Warnings.Count.ShouldBe(1, result); - result.Warnings.Count(i => i.Id == Core.LogId.WarningLifetimeDefect).ShouldBe(1, result); + result.Errors.Count.ShouldBe(1, result); + result.Errors.Count(i => i.Id == Core.LogId.ErrorLifetimeDefect).ShouldBe(1, result); } [Fact] - public async Task ShouldShowWarningWhenSingletonIndirectInjectsScoped() + public async Task ShouldShowErrorWhenSingletonIndirectInjectsScoped() { // Given @@ -2823,8 +2822,7 @@ public static void Main() // Then result.Success.ShouldBeFalse(result); - result.StdOut.ShouldBe(["True", "True", "True", "True", "True", "True", "True", "True", "True"], result); - result.Warnings.Count.ShouldBe(1, result); - result.Warnings.Count(i => i.Id == Core.LogId.WarningLifetimeDefect).ShouldBe(1, result); + result.Errors.Count.ShouldBe(1, result); + result.Errors.Count(i => i.Id == Core.LogId.ErrorLifetimeDefect).ShouldBe(1, result); } } \ No newline at end of file