From 255a8a8ad95f654229d03e3727a0bde71c7acae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=B2=D0=B4=D0=B5=D0=B5=D0=B2=20=D0=92=D1=8F=D1=87?= =?UTF-8?q?=D0=B5=D1=81=D0=BB=D0=B0=D0=B2?= Date: Wed, 5 Jul 2023 10:36:58 +0500 Subject: [PATCH] prototype --- .../Unit/UselessConstructorArgumentTests.cs | 77 +++++++++++++++++++ .../Activation/Providers/StandardProvider.cs | 29 ++++++- src/Ninject/INinjectSettings.cs | 7 ++ src/Ninject/NinjectSettings.cs | 10 +++ 4 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/Ninject.Test/Unit/UselessConstructorArgumentTests.cs diff --git a/src/Ninject.Test/Unit/UselessConstructorArgumentTests.cs b/src/Ninject.Test/Unit/UselessConstructorArgumentTests.cs new file mode 100644 index 00000000..faad5f62 --- /dev/null +++ b/src/Ninject.Test/Unit/UselessConstructorArgumentTests.cs @@ -0,0 +1,77 @@ +namespace Ninject.Tests.Unit +{ + using System; + using FluentAssertions; + using Ninject; + using Xunit; + + public class UselessConstructorArgumentTests + { + public UselessConstructorArgumentTests() + { + } + + [Fact] + public void UselessConstructorArgument_FailedTest() + { + using (var kernel = new StandardKernel()) + { + kernel.Settings.CheckForUselessConstructorArgument = true; + + kernel.Bind().ToSelf() + .WithConstructorArgument("power", 100) + .WithConstructorArgument("pulseInterval", TimeSpan.FromSeconds(1)) + .WithConstructorArgument("unknownArgument", 1) + ; + + Action getLaser = () => kernel.Get(); + + getLaser.ShouldThrow(); + } + } + + [Fact] + public void UselessConstructorArgument_SuccessfulTest() + { + using (var kernel = new StandardKernel()) + { + kernel.Settings.CheckForUselessConstructorArgument = false; + + kernel.Bind().ToSelf() + .WithConstructorArgument("power", 100) + .WithConstructorArgument("pulseInterval", TimeSpan.FromSeconds(1)) + .WithConstructorArgument("unknownArgument", 1) + ; + + var pulseLaser = kernel.Get(); + pulseLaser.Should().NotBeNull(); + pulseLaser.Power.Should().Be(100); + pulseLaser.PulseInterval.Should().Be(TimeSpan.FromSeconds(1)); + } + } + } + + public class Laser + { + public readonly int Power; + + public Laser( + int power + ) + { + Power = power; + } + } + + public sealed class PulseLaser : Laser + { + public readonly TimeSpan PulseInterval; + + public PulseLaser(int power, TimeSpan pulseInterval) + : base(power) + { + PulseInterval = pulseInterval; + } + } + +} diff --git a/src/Ninject/Activation/Providers/StandardProvider.cs b/src/Ninject/Activation/Providers/StandardProvider.cs index 5d7a39ad..eb8ecb6d 100644 --- a/src/Ninject/Activation/Providers/StandardProvider.cs +++ b/src/Ninject/Activation/Providers/StandardProvider.cs @@ -113,7 +113,34 @@ public virtual object Create(IContext context) context.Plan = this.Planner.GetPlan(this.GetImplementationType(context.Request.Service)); } - var directive = this.DetermineConstructorInjectionDirective(context); + var directive = this.DetermineConstructorInjectionDirective(context); + + #region check if any constructor argument is useless; fail if so + + if (context.Kernel.Settings.CheckForUselessConstructorArgument) + { + foreach (IConstructorArgument constructorArgument in context.Parameters.OfType()) + { + var cpn = constructorArgument.Name; + + var match = false; + foreach (var target in directive.Targets) + { + if (constructorArgument.AppliesToTarget(context, target)) + { + match = true; + break; + } + } + + if (!match) + { + throw new Ninject.ActivationException($"Boom"); + } + } + } + + #endregion var arguments = directive.Targets.Select(target => this.GetValue(context, target)).ToArray(); diff --git a/src/Ninject/INinjectSettings.cs b/src/Ninject/INinjectSettings.cs index 6241416e..c95929d4 100644 --- a/src/Ninject/INinjectSettings.cs +++ b/src/Ninject/INinjectSettings.cs @@ -104,6 +104,13 @@ public interface INinjectSettings /// bool ThrowOnGetServiceNotFound { get; set; } + + /// + /// Gets or sets a value indicating whether Ninject should seek for a useless constructor arguments in the binding + /// and fail the resolution process if it found. + /// + bool CheckForUselessConstructorArgument { get; set; } + /// /// Gets the value for the specified key. /// diff --git a/src/Ninject/NinjectSettings.cs b/src/Ninject/NinjectSettings.cs index 22893eca..fc954b41 100644 --- a/src/Ninject/NinjectSettings.cs +++ b/src/Ninject/NinjectSettings.cs @@ -154,6 +154,16 @@ public bool ThrowOnGetServiceNotFound set { this.Set("ThrowOnGetServiceNotFound", value); } } + /// + /// Gets or sets a value indicating whether Ninject should seek for a useless constructor arguments in the binding + /// and fail the resolution process if it found. + /// + public bool CheckForUselessConstructorArgument + { + get { return this.Get("CheckForUselessConstructorArgument", false); } + set { this.Set("CheckForUselessConstructorArgument", value); } + } + /// /// Gets the value for the specified key. ///