Skip to content

Commit

Permalink
adds interface filtering for AsSelfWithInterfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
leachdaniel-clark authored and khellang committed Sep 25, 2024
1 parent 304a3ad commit f1c4da2
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
8 changes: 7 additions & 1 deletion src/Scrutor/IServiceTypeSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ public interface IServiceTypeSelector : IImplementationTypeSelector
/// </summary>
ILifetimeSelector AsSelfWithInterfaces();

/// <summary>
/// Registers each matching concrete type as all of its implemented interfaces, by returning an instance of the main type
/// </summary>
/// <param name="predicate">A predicate to filter which interfaces to register.</param>
ILifetimeSelector AsSelfWithInterfaces(Func<Type, bool> predicate);

/// <summary>
/// Registers the type with the first found matching interface name. (e.g. ClassName is matched to IClassName)
/// </summary>
Expand All @@ -71,4 +77,4 @@ public interface IServiceTypeSelector : IImplementationTypeSelector
IImplementationTypeSelector UsingAttributes();

IServiceTypeSelector UsingRegistrationStrategy(RegistrationStrategy registrationStrategy);
}
}
7 changes: 6 additions & 1 deletion src/Scrutor/LifetimeSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ public ILifetimeSelector AsSelfWithInterfaces()
return Inner.AsSelfWithInterfaces();
}

public ILifetimeSelector AsSelfWithInterfaces(Func<Type, bool> predicate)
{
return Inner.AsSelfWithInterfaces(predicate);
}

public ILifetimeSelector AsMatchingInterface()
{
return Inner.AsMatchingInterface();
Expand Down Expand Up @@ -229,4 +234,4 @@ void ISelector.Populate(IServiceCollection services, RegistrationStrategy? strat
}
}
}
}
}
8 changes: 7 additions & 1 deletion src/Scrutor/ServiceTypeSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ public ILifetimeSelector AsImplementedInterfaces(Func<Type, bool> predicate)
}

public ILifetimeSelector AsSelfWithInterfaces()
{
return AsSelfWithInterfaces(_ => true);
}

public ILifetimeSelector AsSelfWithInterfaces(Func<Type, bool> predicate)
{
IEnumerable<Type> Selector(Type type)
{
Expand All @@ -75,6 +80,7 @@ IEnumerable<Type> Selector(Type type)

return type.GetInterfaces()
.Where(x => x.HasMatchingGenericArity(type))
.Where(predicate)
.Select(x => x.GetRegistrationType(type));
}

Expand Down Expand Up @@ -237,4 +243,4 @@ private ILifetimeSelector AddSelector(IEnumerable<TypeMap> types, IEnumerable<Ty

return selector;
}
}
}
24 changes: 24 additions & 0 deletions test/Scrutor.Tests/ScanningTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,30 @@ public void AsSelfWithInterfacesShouldCreateTrueSingletons()
Assert.Same(instance1, instance5);
}

[Fact]
public void AsSelfWithInterfacesShouldFilterInterfaces()
{
var provider = ConfigureProvider(services =>
{
services.Scan(scan => scan
.FromAssemblyOf<CombinedService2>()
.AddClasses(classes => classes.AssignableTo<CombinedService2>())
.AsSelfWithInterfaces(x => x == typeof(IDefault1) || x == typeof(CombinedService2))
.WithSingletonLifetime());
});

var instance1 = provider.GetRequiredService<CombinedService2>();
var instance2 = provider.GetRequiredService<IDefault1>();
var instance3 = provider.GetService<IDefault2>();
var instance4 = provider.GetService<IDefault3Level2>();
var instance5 = provider.GetService<IDefault3Level1>();

Assert.Same(instance1, instance2);
Assert.Null(instance3);
Assert.Null(instance4);
Assert.Null(instance5);
}

[Fact]
public void AsSelfWithInterfacesHandlesOpenGenericTypes()
{
Expand Down

0 comments on commit f1c4da2

Please sign in to comment.