From 771d952d03a699804014690e796ed5f92088f293 Mon Sep 17 00:00:00 2001 From: Alex Dresko Date: Thu, 18 Dec 2025 23:27:54 -0500 Subject: [PATCH 1/7] feat!: rename AddAdvancedDependencyInjection to AddEasyScrutor BREAKING CHANGE: Renamed AddAdvancedDependencyInjection method to AddEasyScrutor for better alignment with package name. Also added new assembly filtering methods AddEasyScrutorForAssembliesStartingWith and AddEasyScrutorForAssembliesContaining. --- .../ServiceCollectionExtensions.cs | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/EasyScrutor/ServiceCollectionExtensions.cs b/src/EasyScrutor/ServiceCollectionExtensions.cs index 69e8dcc..f30137b 100644 --- a/src/EasyScrutor/ServiceCollectionExtensions.cs +++ b/src/EasyScrutor/ServiceCollectionExtensions.cs @@ -15,7 +15,7 @@ public static class ServiceCollectionExtensions { /// /// The service collection to add services to. /// The service collection for chaining. - public static IServiceCollection AddAdvancedDependencyInjection(this IServiceCollection services) { + public static IServiceCollection AddEasyScrutor(this IServiceCollection services) { services.Scan(scan => scan .FromDependencyContext(DependencyModel.DependencyContext.Default) .AddClassesFromInterfaces()); @@ -30,7 +30,7 @@ public static IServiceCollection AddAdvancedDependencyInjection(this IServiceCol /// The service collection to add services to. /// A predicate to filter which assemblies to scan. /// The service collection for chaining. - public static IServiceCollection AddAdvancedDependencyInjection(this IServiceCollection services, Func predicate) { + public static IServiceCollection AddEasyScrutor(this IServiceCollection services, Func predicate) { services.Scan(scan => scan .FromDependencyContext(DependencyModel.DependencyContext.Default, predicate) .AddClassesFromInterfaces()); @@ -38,6 +38,36 @@ public static IServiceCollection AddAdvancedDependencyInjection(this IServiceCol return services; } + /// + /// Scans and registers services from assemblies whose names start with the specified prefix. + /// Services are registered based on their implemented lifetime interfaces (ISingletonLifetime, ITransientLifetime, IScopedLifetime). + /// + /// The service collection to add services to. + /// The prefix that assembly names must start with. + /// The service collection for chaining. + public static IServiceCollection AddEasyScrutorForAssembliesStartingWith(this IServiceCollection services, string prefix) { + services.Scan(scan => scan + .FromDependencyContext(DependencyModel.DependencyContext.Default, assembly => assembly.FullName?.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) == true) + .AddClassesFromInterfaces()); + + return services; + } + + /// + /// Scans and registers services from assemblies whose names contain the specified text. + /// Services are registered based on their implemented lifetime interfaces (ISingletonLifetime, ITransientLifetime, IScopedLifetime). + /// + /// The service collection to add services to. + /// The text that assembly names must contain. + /// The service collection for chaining. + public static IServiceCollection AddEasyScrutorForAssembliesContaining(this IServiceCollection services, string text) { + services.Scan(scan => scan + .FromDependencyContext(DependencyModel.DependencyContext.Default, assembly => assembly.FullName?.Contains(text, StringComparison.OrdinalIgnoreCase) == true) + .AddClassesFromInterfaces()); + + return services; + } + /// /// Configures service registration based on lifetime marker interfaces. /// Scans for classes implementing ISingletonLifetime, ITransientLifetime, IScopedLifetime, and their self-registration variants. From 5b99dd17148695b96520b242a26d4bd69f2c0f0a Mon Sep 17 00:00:00 2001 From: Alex Dresko Date: Thu, 18 Dec 2025 23:28:14 -0500 Subject: [PATCH 2/7] test: add comprehensive tests for assembly filter methods Added AssemblyFilterTests with 13 test cases covering: - AddEasyScrutorForAssembliesStartingWith functionality - AddEasyScrutorForAssembliesContaining functionality - Case-insensitive matching behavior - Negative test cases for non-matching assemblies --- .../EasyScrutor.Tests/AssemblyFilterTests.cs | 241 ++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 tests/EasyScrutor.Tests/AssemblyFilterTests.cs diff --git a/tests/EasyScrutor.Tests/AssemblyFilterTests.cs b/tests/EasyScrutor.Tests/AssemblyFilterTests.cs new file mode 100644 index 0000000..2f2c6b9 --- /dev/null +++ b/tests/EasyScrutor.Tests/AssemblyFilterTests.cs @@ -0,0 +1,241 @@ +using EasyScrutor.Tests.TestServices; +using System.Reflection; + +namespace EasyScrutor.Tests; + +/// +/// Tests for assembly filtering methods like AddEasyScrutorForAssembliesStartingWith and AddEasyScrutorForAssembliesContaining. +/// +[TestFixture] +public class AssemblyFilterTests { + [Test] + public void AddEasyScrutorForAssembliesStartingWith_MatchingPrefix_ShouldRegisterServices() { + // Arrange + var services = new ServiceCollection(); + var testAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; + var prefix = testAssemblyName!.Substring(0, 10); // Get first 10 characters as prefix + + // Act + services.AddEasyScrutorForAssembliesStartingWith(prefix); + var serviceProvider = services.BuildServiceProvider(); + + // Assert + Assert.That(serviceProvider.GetService(), Is.Not.Null); + Assert.That(serviceProvider.GetService(), Is.Not.Null); + Assert.That(serviceProvider.GetService(), Is.Not.Null); + } + + [Test] + public void AddEasyScrutorForAssembliesStartingWith_NonMatchingPrefix_ShouldNotRegisterServices() { + // Arrange + var services = new ServiceCollection(); + + // Act + services.AddEasyScrutorForAssembliesStartingWith("NonExistentPrefix"); + var serviceProvider = services.BuildServiceProvider(); + + // Assert + Assert.That(serviceProvider.GetService(), Is.Null); + Assert.That(serviceProvider.GetService(), Is.Null); + Assert.That(serviceProvider.GetService(), Is.Null); + } + + [Test] + public void AddEasyScrutorForAssembliesStartingWith_CaseInsensitive_ShouldRegisterServices() { + // Arrange + var services = new ServiceCollection(); + var testAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; + var prefix = testAssemblyName!.Substring(0, 10).ToLower(); // Lowercase prefix + + // Act + services.AddEasyScrutorForAssembliesStartingWith(prefix); + var serviceProvider = services.BuildServiceProvider(); + + // Assert + Assert.That(serviceProvider.GetService(), Is.Not.Null, "Should be case-insensitive"); + } + + [Test] + public void AddEasyScrutorForAssembliesStartingWith_ShouldReturnServiceCollection_ForChaining() { + // Arrange + var services = new ServiceCollection(); + + // Act + var result = services.AddEasyScrutorForAssembliesStartingWith("Test"); + + // Assert + Assert.That(result, Is.SameAs(services), "Should return the same ServiceCollection for method chaining"); + } + + [Test] + public void AddEasyScrutorForAssembliesContaining_MatchingText_ShouldRegisterServices() { + // Arrange + var services = new ServiceCollection(); + var testAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; + var containingText = "Scrutor"; // Should be part of the assembly name + + // Act + services.AddEasyScrutorForAssembliesContaining(containingText); + var serviceProvider = services.BuildServiceProvider(); + + // Assert + Assert.That(serviceProvider.GetService(), Is.Not.Null); + Assert.That(serviceProvider.GetService(), Is.Not.Null); + Assert.That(serviceProvider.GetService(), Is.Not.Null); + } + + [Test] + public void AddEasyScrutorForAssembliesContaining_NonMatchingText_ShouldNotRegisterServices() { + // Arrange + var services = new ServiceCollection(); + + // Act + services.AddEasyScrutorForAssembliesContaining("NonExistentText"); + var serviceProvider = services.BuildServiceProvider(); + + // Assert + Assert.That(serviceProvider.GetService(), Is.Null); + Assert.That(serviceProvider.GetService(), Is.Null); + Assert.That(serviceProvider.GetService(), Is.Null); + } + + [Test] + public void AddEasyScrutorForAssembliesContaining_CaseInsensitive_ShouldRegisterServices() { + // Arrange + var services = new ServiceCollection(); + var containingText = "SCRUTOR"; // Uppercase + + // Act + services.AddEasyScrutorForAssembliesContaining(containingText); + var serviceProvider = services.BuildServiceProvider(); + + // Assert + Assert.That(serviceProvider.GetService(), Is.Not.Null, "Should be case-insensitive"); + } + + [Test] + public void AddEasyScrutorForAssembliesContaining_ShouldReturnServiceCollection_ForChaining() { + // Arrange + var services = new ServiceCollection(); + + // Act + var result = services.AddEasyScrutorForAssembliesContaining("Test"); + + // Assert + Assert.That(result, Is.SameAs(services), "Should return the same ServiceCollection for method chaining"); + } + + [Test] + public void AddEasyScrutorForAssembliesContaining_PartialMatch_ShouldRegisterServices() { + // Arrange + var services = new ServiceCollection(); + var testAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; + // Take middle part of assembly name + var partialText = testAssemblyName!.Substring(5, 5); + + // Act + services.AddEasyScrutorForAssembliesContaining(partialText); + var serviceProvider = services.BuildServiceProvider(); + + // Assert + Assert.That(serviceProvider.GetService(), Is.Not.Null, "Should match partial text"); + } + + [Test] + public void AddEasyScrutorForAssembliesStartingWith_CalledMultipleTimes_ShouldSkipDuplicates() { + // Arrange + var services = new ServiceCollection(); + var testAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; + var prefix = testAssemblyName!.Substring(0, 10); + + // Act + services.AddEasyScrutorForAssembliesStartingWith(prefix); + services.AddEasyScrutorForAssembliesStartingWith(prefix); + + // Assert - Should only have one registration due to Skip strategy + var singletonServices = services.Where(s => s.ServiceType == typeof(ISingletonService)).ToList(); + Assert.That(singletonServices.Count, Is.EqualTo(1), "Should not register duplicate services"); + } + + [Test] + public void AddEasyScrutorForAssembliesContaining_CalledMultipleTimes_ShouldSkipDuplicates() { + // Arrange + var services = new ServiceCollection(); + + // Act + services.AddEasyScrutorForAssembliesContaining("Scrutor"); + services.AddEasyScrutorForAssembliesContaining("Scrutor"); + + // Assert - Should only have one registration due to Skip strategy + var singletonServices = services.Where(s => s.ServiceType == typeof(ISingletonService)).ToList(); + Assert.That(singletonServices.Count, Is.EqualTo(1), "Should not register duplicate services"); + } + + [Test] + public void AddEasyScrutorForAssembliesStartingWith_AllLifetimeInterfaces_ShouldBeRegistered() { + // Arrange + var services = new ServiceCollection(); + var testAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; + var prefix = testAssemblyName!.Substring(0, 10); + + // Act + services.AddEasyScrutorForAssembliesStartingWith(prefix); + var serviceProvider = services.BuildServiceProvider(); + + // Assert - Verify all 6 lifetime interfaces are working + using var scope = serviceProvider.CreateScope(); + + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "ISingletonLifetime should work"); + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "ISelfSingletonLifetime should work"); + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "ITransientLifetime should work"); + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "ISelfTransientLifetime should work"); + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "IScopedLifetime should work"); + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "ISelfScopedLifetime should work"); + } + + [Test] + public void AddEasyScrutorForAssembliesContaining_AllLifetimeInterfaces_ShouldBeRegistered() { + // Arrange + var services = new ServiceCollection(); + + // Act + services.AddEasyScrutorForAssembliesContaining("Scrutor"); + var serviceProvider = services.BuildServiceProvider(); + + // Assert - Verify all 6 lifetime interfaces are working + using var scope = serviceProvider.CreateScope(); + + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "ISingletonLifetime should work"); + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "ISelfSingletonLifetime should work"); + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "ITransientLifetime should work"); + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "ISelfTransientLifetime should work"); + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "IScopedLifetime should work"); + Assert.That(scope.ServiceProvider.GetService(), Is.Not.Null, "ISelfScopedLifetime should work"); + } + + [Test] + public void AddEasyScrutorForAssembliesStartingWith_EmptyPrefix_ShouldMatchAllAssemblies() { + // Arrange + var services = new ServiceCollection(); + + // Act + services.AddEasyScrutorForAssembliesStartingWith(""); + var serviceProvider = services.BuildServiceProvider(); + + // Assert - Empty prefix matches everything + Assert.That(serviceProvider.GetService(), Is.Not.Null); + } + + [Test] + public void AddEasyScrutorForAssembliesContaining_EmptyText_ShouldMatchAllAssemblies() { + // Arrange + var services = new ServiceCollection(); + + // Act + services.AddEasyScrutorForAssembliesContaining(""); + var serviceProvider = services.BuildServiceProvider(); + + // Assert - Empty text matches everything + Assert.That(serviceProvider.GetService(), Is.Not.Null); + } +} From a7d3c6d83e405f448c6c645a845bfa3bc26f7212 Mon Sep 17 00:00:00 2001 From: Alex Dresko Date: Thu, 18 Dec 2025 23:28:31 -0500 Subject: [PATCH 3/7] test: update existing tests to use AddEasyScrutor Updated all test files to use the renamed AddEasyScrutor method instead of AddAdvancedDependencyInjection. --- .../AdvancedDependencyInjectionTests.cs | 32 +++++++++---------- .../EasyScrutor.Tests/ScopedLifetimeTests.cs | 2 +- .../ServiceLifecycleIntegrationTests.cs | 12 +++---- .../SingletonLifetimeTests.cs | 2 +- .../TransientLifetimeTests.cs | 2 +- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/EasyScrutor.Tests/AdvancedDependencyInjectionTests.cs b/tests/EasyScrutor.Tests/AdvancedDependencyInjectionTests.cs index 42d93ea..72f272d 100644 --- a/tests/EasyScrutor.Tests/AdvancedDependencyInjectionTests.cs +++ b/tests/EasyScrutor.Tests/AdvancedDependencyInjectionTests.cs @@ -6,12 +6,12 @@ namespace EasyScrutor.Tests; [TestFixture] public class AdvancedDependencyInjectionTests { [Test] - public void AddAdvancedDependencyInjection_WithoutPredicate_ShouldRegisterAllServices() { + public void AddEasyScrutor_WithoutPredicate_ShouldRegisterAllServices() { // Arrange var services = new ServiceCollection(); // Act - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); var serviceProvider = services.BuildServiceProvider(); // Assert @@ -24,13 +24,13 @@ public void AddAdvancedDependencyInjection_WithoutPredicate_ShouldRegisterAllSer } [Test] - public void AddAdvancedDependencyInjection_WithPredicate_ShouldOnlyRegisterMatchingAssemblies() { + public void AddEasyScrutor_WithPredicate_ShouldOnlyRegisterMatchingAssemblies() { // Arrange var services = new ServiceCollection(); var testAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; // Act - services.AddAdvancedDependencyInjection(assembly => + services.AddEasyScrutor(assembly => assembly.FullName != null && assembly.FullName.Contains(testAssemblyName!)); var serviceProvider = services.BuildServiceProvider(); @@ -41,12 +41,12 @@ public void AddAdvancedDependencyInjection_WithPredicate_ShouldOnlyRegisterMatch } [Test] - public void AddAdvancedDependencyInjection_WithExcludingPredicate_ShouldNotRegisterFilteredAssemblies() { + public void AddEasyScrutor_WithExcludingPredicate_ShouldNotRegisterFilteredAssemblies() { // Arrange var services = new ServiceCollection(); // Act - Exclude assemblies containing "NonExistent" - services.AddAdvancedDependencyInjection(assembly => + services.AddEasyScrutor(assembly => assembly.FullName != null && !assembly.FullName.Contains("NonExistent")); var serviceProvider = services.BuildServiceProvider(); @@ -55,13 +55,13 @@ public void AddAdvancedDependencyInjection_WithExcludingPredicate_ShouldNotRegis } [Test] - public void AddAdvancedDependencyInjection_CalledMultipleTimes_ShouldSkipDuplicates() { + public void AddEasyScrutor_CalledMultipleTimes_ShouldSkipDuplicates() { // Arrange var services = new ServiceCollection(); // Act - services.AddAdvancedDependencyInjection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); + services.AddEasyScrutor(); // Assert - Should only have one registration due to Skip strategy var singletonServices = services.Where(s => s.ServiceType == typeof(ISingletonService)).ToList(); @@ -74,7 +74,7 @@ public void ServiceRegistration_ShouldRespectRegistrationStrategy() { var services = new ServiceCollection(); // Act - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); // Try to add a manual registration - it should be skipped due to RegistrationStrategy.Skip services.AddSingleton(); @@ -89,7 +89,7 @@ public void ServiceRegistration_ShouldRespectRegistrationStrategy() { public void ComplexService_WithDependencies_ShouldResolveCorrectly() { // Arrange var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); var serviceProvider = services.BuildServiceProvider(); // Act @@ -110,7 +110,7 @@ public void ServiceCollection_ShouldReturnItself_ForChaining() { var services = new ServiceCollection(); // Act - var result = services.AddAdvancedDependencyInjection(); + var result = services.AddEasyScrutor(); // Assert Assert.That(result, Is.SameAs(services), "Should return the same ServiceCollection for method chaining"); @@ -120,7 +120,7 @@ public void ServiceCollection_ShouldReturnItself_ForChaining() { public void AllLifetimeInterfaces_ShouldBeRegistered() { // Arrange var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); var serviceProvider = services.BuildServiceProvider(); // Act & Assert - Verify all 6 lifetime interfaces are working @@ -138,7 +138,7 @@ public void AllLifetimeInterfaces_ShouldBeRegistered() { public void MultipleImplementations_ShouldRegisterFirst() { // Arrange var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); var serviceProvider = services.BuildServiceProvider(); // Act @@ -154,7 +154,7 @@ public void MultipleImplementations_ShouldRegisterFirst() { public void AbstractBaseClass_ShouldNotBeRegistered() { // Arrange var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); // Act var abstractRegistrations = services.Where(s => s.ImplementationType == typeof(BaseService)).ToList(); @@ -167,7 +167,7 @@ public void AbstractBaseClass_ShouldNotBeRegistered() { public void ConcreteClassFromAbstract_ShouldBeRegistered() { // Arrange var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); var serviceProvider = services.BuildServiceProvider(); // Act diff --git a/tests/EasyScrutor.Tests/ScopedLifetimeTests.cs b/tests/EasyScrutor.Tests/ScopedLifetimeTests.cs index 3b93610..2a49eb3 100644 --- a/tests/EasyScrutor.Tests/ScopedLifetimeTests.cs +++ b/tests/EasyScrutor.Tests/ScopedLifetimeTests.cs @@ -9,7 +9,7 @@ public class ScopedLifetimeTests { [SetUp] public void Setup() { var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); _serviceProvider = services.BuildServiceProvider(); } diff --git a/tests/EasyScrutor.Tests/ServiceLifecycleIntegrationTests.cs b/tests/EasyScrutor.Tests/ServiceLifecycleIntegrationTests.cs index ad67e62..386ce75 100644 --- a/tests/EasyScrutor.Tests/ServiceLifecycleIntegrationTests.cs +++ b/tests/EasyScrutor.Tests/ServiceLifecycleIntegrationTests.cs @@ -8,7 +8,7 @@ public class ServiceLifecycleIntegrationTests { public void MixedLifetimes_ShouldWorkTogetherCorrectly() { // Arrange var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); var serviceProvider = services.BuildServiceProvider(); // Act @@ -60,7 +60,7 @@ public void MixedLifetimes_ShouldWorkTogetherCorrectly() { public void ComplexService_ShouldReceiveCorrectDependencies() { // Arrange var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); var serviceProvider = services.BuildServiceProvider(); // Act @@ -95,7 +95,7 @@ public void ComplexService_ShouldReceiveCorrectDependencies() { public void SelfRegisteredServices_ShouldOnlyBeAvailableAsSelf() { // Arrange var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); var serviceProvider = services.BuildServiceProvider(); // Act @@ -113,7 +113,7 @@ public void SelfRegisteredServices_ShouldOnlyBeAvailableAsSelf() { public void InterfaceRegisteredServices_ShouldBeAvailableViaInterface() { // Arrange var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); var serviceProvider = services.BuildServiceProvider(); // Act @@ -131,7 +131,7 @@ public void InterfaceRegisteredServices_ShouldBeAvailableViaInterface() { public void InterfaceRegisteredServices_ShouldNotBeAvailableAsConcreteType() { // Arrange var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); var serviceProvider = services.BuildServiceProvider(); // Act @@ -149,7 +149,7 @@ public void InterfaceRegisteredServices_ShouldNotBeAvailableAsConcreteType() { public void ServiceProvider_Dispose_ShouldDisposeDisposableServices() { // Arrange var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); using (var serviceProvider = services.BuildServiceProvider()) { // Act var singleton = serviceProvider.GetService(); diff --git a/tests/EasyScrutor.Tests/SingletonLifetimeTests.cs b/tests/EasyScrutor.Tests/SingletonLifetimeTests.cs index c14bff9..a759d89 100644 --- a/tests/EasyScrutor.Tests/SingletonLifetimeTests.cs +++ b/tests/EasyScrutor.Tests/SingletonLifetimeTests.cs @@ -9,7 +9,7 @@ public class SingletonLifetimeTests { [SetUp] public void Setup() { var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); _serviceProvider = services.BuildServiceProvider(); } diff --git a/tests/EasyScrutor.Tests/TransientLifetimeTests.cs b/tests/EasyScrutor.Tests/TransientLifetimeTests.cs index 95074b4..68a0dd0 100644 --- a/tests/EasyScrutor.Tests/TransientLifetimeTests.cs +++ b/tests/EasyScrutor.Tests/TransientLifetimeTests.cs @@ -9,7 +9,7 @@ public class TransientLifetimeTests { [SetUp] public void Setup() { var services = new ServiceCollection(); - services.AddAdvancedDependencyInjection(); + services.AddEasyScrutor(); _serviceProvider = services.BuildServiceProvider(); } From fe74eb69fb3c8dd5fe73ed320d702005d8a779b0 Mon Sep 17 00:00:00 2001 From: Alex Dresko Date: Thu, 18 Dec 2025 23:28:46 -0500 Subject: [PATCH 4/7] docs: update example projects to use AddEasyScrutor Updated all example applications (BlazorServer, ConsoleHost, Mvc, WebApi) to use the renamed AddEasyScrutor method. --- examples/BlazorServerExample/Program.cs | 2 +- examples/ConsoleHostExample/Program.cs | 2 +- examples/MvcExample/Program.cs | 2 +- examples/WebApiExample/Program.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/BlazorServerExample/Program.cs b/examples/BlazorServerExample/Program.cs index 2cc39e8..e2bc813 100644 --- a/examples/BlazorServerExample/Program.cs +++ b/examples/BlazorServerExample/Program.cs @@ -8,7 +8,7 @@ builder.Services.AddSingleton(); // Add EasyScrutor - Automatically scans and registers services -builder.Services.AddAdvancedDependencyInjection(); +builder.Services.AddEasyScrutor(); var app = builder.Build(); diff --git a/examples/ConsoleHostExample/Program.cs b/examples/ConsoleHostExample/Program.cs index 5bc8aff..74110f6 100644 --- a/examples/ConsoleHostExample/Program.cs +++ b/examples/ConsoleHostExample/Program.cs @@ -4,7 +4,7 @@ // Add EasyScrutor - Automatically scans and registers all services // This will find and register IDataProcessor and IMetricsCollector without manual configuration -builder.Services.AddAdvancedDependencyInjection(); +builder.Services.AddEasyScrutor(); builder.Services.AddHostedService(); diff --git a/examples/MvcExample/Program.cs b/examples/MvcExample/Program.cs index 1996a6f..1500519 100644 --- a/examples/MvcExample/Program.cs +++ b/examples/MvcExample/Program.cs @@ -4,7 +4,7 @@ builder.Services.AddControllersWithViews(); // Add EasyScrutor - Automatically scans and registers services -builder.Services.AddAdvancedDependencyInjection(); +builder.Services.AddEasyScrutor(); var app = builder.Build(); diff --git a/examples/WebApiExample/Program.cs b/examples/WebApiExample/Program.cs index 8e6f8ec..bc2d6e5 100644 --- a/examples/WebApiExample/Program.cs +++ b/examples/WebApiExample/Program.cs @@ -7,7 +7,7 @@ builder.Services.AddOpenApi(); // Add EasyScrutor - Automatically scans and registers services based on lifetime interfaces -builder.Services.AddAdvancedDependencyInjection(); +builder.Services.AddEasyScrutor(); var app = builder.Build(); From cdb7c36167b6c32535eaccbc3ce000a7abee24df Mon Sep 17 00:00:00 2001 From: Alex Dresko Date: Thu, 18 Dec 2025 23:33:28 -0500 Subject: [PATCH 5/7] fix: Potential fix for code scanning alert no. 4: Useless assignment to local variable Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- tests/EasyScrutor.Tests/AssemblyFilterTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/EasyScrutor.Tests/AssemblyFilterTests.cs b/tests/EasyScrutor.Tests/AssemblyFilterTests.cs index 2f2c6b9..490e02f 100644 --- a/tests/EasyScrutor.Tests/AssemblyFilterTests.cs +++ b/tests/EasyScrutor.Tests/AssemblyFilterTests.cs @@ -71,7 +71,6 @@ public void AddEasyScrutorForAssembliesStartingWith_ShouldReturnServiceCollectio public void AddEasyScrutorForAssembliesContaining_MatchingText_ShouldRegisterServices() { // Arrange var services = new ServiceCollection(); - var testAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; var containingText = "Scrutor"; // Should be part of the assembly name // Act From 8a8bb2811a57cfef6fb85dbc2a68981cf0f24f36 Mon Sep 17 00:00:00 2001 From: Alex Dresko Date: Thu, 18 Dec 2025 23:36:56 -0500 Subject: [PATCH 6/7] refactor: improve branch coverage for assembly filter predicates Changed null-conditional operators to explicit null checks for better test coverage. Now achieves 100% line and branch coverage. --- src/EasyScrutor/ServiceCollectionExtensions.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/EasyScrutor/ServiceCollectionExtensions.cs b/src/EasyScrutor/ServiceCollectionExtensions.cs index f30137b..f55d9f0 100644 --- a/src/EasyScrutor/ServiceCollectionExtensions.cs +++ b/src/EasyScrutor/ServiceCollectionExtensions.cs @@ -47,7 +47,8 @@ public static IServiceCollection AddEasyScrutor(this IServiceCollection services /// The service collection for chaining. public static IServiceCollection AddEasyScrutorForAssembliesStartingWith(this IServiceCollection services, string prefix) { services.Scan(scan => scan - .FromDependencyContext(DependencyModel.DependencyContext.Default, assembly => assembly.FullName?.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) == true) + .FromDependencyContext(DependencyModel.DependencyContext.Default, assembly => + assembly.FullName != null && assembly.FullName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) .AddClassesFromInterfaces()); return services; @@ -62,7 +63,8 @@ public static IServiceCollection AddEasyScrutorForAssembliesStartingWith(this IS /// The service collection for chaining. public static IServiceCollection AddEasyScrutorForAssembliesContaining(this IServiceCollection services, string text) { services.Scan(scan => scan - .FromDependencyContext(DependencyModel.DependencyContext.Default, assembly => assembly.FullName?.Contains(text, StringComparison.OrdinalIgnoreCase) == true) + .FromDependencyContext(DependencyModel.DependencyContext.Default, assembly => + assembly.FullName != null && assembly.FullName.Contains(text, StringComparison.OrdinalIgnoreCase)) .AddClassesFromInterfaces()); return services; From b74bd39682eef26c58fbf6c9d318c6bcc4aa501b Mon Sep 17 00:00:00 2001 From: Alex Dresko Date: Thu, 18 Dec 2025 23:38:39 -0500 Subject: [PATCH 7/7] refactor: formatting --- src/EasyScrutor/ServiceCollectionExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EasyScrutor/ServiceCollectionExtensions.cs b/src/EasyScrutor/ServiceCollectionExtensions.cs index f55d9f0..ea8a899 100644 --- a/src/EasyScrutor/ServiceCollectionExtensions.cs +++ b/src/EasyScrutor/ServiceCollectionExtensions.cs @@ -47,7 +47,7 @@ public static IServiceCollection AddEasyScrutor(this IServiceCollection services /// The service collection for chaining. public static IServiceCollection AddEasyScrutorForAssembliesStartingWith(this IServiceCollection services, string prefix) { services.Scan(scan => scan - .FromDependencyContext(DependencyModel.DependencyContext.Default, assembly => + .FromDependencyContext(DependencyModel.DependencyContext.Default, assembly => assembly.FullName != null && assembly.FullName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) .AddClassesFromInterfaces()); @@ -63,7 +63,7 @@ public static IServiceCollection AddEasyScrutorForAssembliesStartingWith(this IS /// The service collection for chaining. public static IServiceCollection AddEasyScrutorForAssembliesContaining(this IServiceCollection services, string text) { services.Scan(scan => scan - .FromDependencyContext(DependencyModel.DependencyContext.Default, assembly => + .FromDependencyContext(DependencyModel.DependencyContext.Default, assembly => assembly.FullName != null && assembly.FullName.Contains(text, StringComparison.OrdinalIgnoreCase)) .AddClassesFromInterfaces());