From 4f444a1a85e4c912a7d81145f42fbd6af1028550 Mon Sep 17 00:00:00 2001 From: Daniel Leach Date: Fri, 21 Jun 2024 10:31:45 -0400 Subject: [PATCH] adds interface filtering for AsSelfWithInterfaces --- src/Scrutor/IServiceTypeSelector.cs | 8 +++++++- src/Scrutor/LifetimeSelector.cs | 7 ++++++- src/Scrutor/ServiceTypeSelector.cs | 8 +++++++- test/Scrutor.Tests/ScanningTests.cs | 24 ++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/Scrutor/IServiceTypeSelector.cs b/src/Scrutor/IServiceTypeSelector.cs index d1f16529..7dc8d015 100644 --- a/src/Scrutor/IServiceTypeSelector.cs +++ b/src/Scrutor/IServiceTypeSelector.cs @@ -46,6 +46,12 @@ public interface IServiceTypeSelector : IImplementationTypeSelector /// ILifetimeSelector AsSelfWithInterfaces(); + /// + /// Registers each matching concrete type as all of its implemented interfaces, by returning an instance of the main type + /// + /// A predicate to filter which interfaces to register. + ILifetimeSelector AsSelfWithInterfaces(Func predicate); + /// /// Registers the type with the first found matching interface name. (e.g. ClassName is matched to IClassName) /// @@ -71,4 +77,4 @@ public interface IServiceTypeSelector : IImplementationTypeSelector IImplementationTypeSelector UsingAttributes(); IServiceTypeSelector UsingRegistrationStrategy(RegistrationStrategy registrationStrategy); -} \ No newline at end of file +} diff --git a/src/Scrutor/LifetimeSelector.cs b/src/Scrutor/LifetimeSelector.cs index 645e498a..51e2ea46 100644 --- a/src/Scrutor/LifetimeSelector.cs +++ b/src/Scrutor/LifetimeSelector.cs @@ -169,6 +169,11 @@ public ILifetimeSelector AsSelfWithInterfaces() return Inner.AsSelfWithInterfaces(); } + public ILifetimeSelector AsSelfWithInterfaces(Func predicate) + { + return Inner.AsSelfWithInterfaces(predicate); + } + public ILifetimeSelector AsMatchingInterface() { return Inner.AsMatchingInterface(); @@ -229,4 +234,4 @@ void ISelector.Populate(IServiceCollection services, RegistrationStrategy? strat } } } -} \ No newline at end of file +} diff --git a/src/Scrutor/ServiceTypeSelector.cs b/src/Scrutor/ServiceTypeSelector.cs index 4843da3b..31fa18e6 100644 --- a/src/Scrutor/ServiceTypeSelector.cs +++ b/src/Scrutor/ServiceTypeSelector.cs @@ -63,6 +63,11 @@ public ILifetimeSelector AsImplementedInterfaces(Func predicate) } public ILifetimeSelector AsSelfWithInterfaces() + { + return AsSelfWithInterfaces(_ => true); + } + + public ILifetimeSelector AsSelfWithInterfaces(Func predicate) { IEnumerable Selector(Type type) { @@ -75,6 +80,7 @@ IEnumerable Selector(Type type) return type.GetInterfaces() .Where(x => x.HasMatchingGenericArity(type)) + .Where(predicate) .Select(x => x.GetRegistrationType(type)); } @@ -237,4 +243,4 @@ private ILifetimeSelector AddSelector(IEnumerable types, IEnumerable + { + services.Scan(scan => scan + .FromAssemblyOf() + .AddClasses(classes => classes.AssignableTo()) + .AsSelfWithInterfaces(x => x == typeof(IDefault1) || x == typeof(CombinedService2)) + .WithSingletonLifetime()); + }); + + var instance1 = provider.GetRequiredService(); + var instance2 = provider.GetRequiredService(); + var instance3 = provider.GetService(); + var instance4 = provider.GetService(); + var instance5 = provider.GetService(); + + Assert.Same(instance1, instance2); + Assert.Null(instance3); + Assert.Null(instance4); + Assert.Null(instance5); + } + [Fact] public void AsSelfWithInterfacesHandlesOpenGenericTypes() {