diff --git a/src/Scrutor/ILifetimeSelector.cs b/src/Scrutor/ILifetimeSelector.cs
index 344424b1..ba7771a2 100644
--- a/src/Scrutor/ILifetimeSelector.cs
+++ b/src/Scrutor/ILifetimeSelector.cs
@@ -1,4 +1,5 @@
-using Microsoft.Extensions.DependencyInjection;
+using System;
+using Microsoft.Extensions.DependencyInjection;
namespace Scrutor;
@@ -23,4 +24,9 @@ public interface ILifetimeSelector : IServiceTypeSelector
/// Registers each matching concrete type with the specified .
///
IImplementationTypeSelector WithLifetime(ServiceLifetime lifetime);
+
+ ///
+ /// Registers each matching concrete type with the specified .
+ ///
+ IImplementationTypeSelector WithLifetime(Func lifetime);
}
diff --git a/src/Scrutor/LifetimeSelector.cs b/src/Scrutor/LifetimeSelector.cs
index 51e2ea46..0c224902 100644
--- a/src/Scrutor/LifetimeSelector.cs
+++ b/src/Scrutor/LifetimeSelector.cs
@@ -21,7 +21,7 @@ public LifetimeSelector(ServiceTypeSelector inner, IEnumerable typeMaps
private IEnumerable TypeFactoryMaps { get; }
- public ServiceLifetime? Lifetime { get; set; }
+ public Func? Lifetime { get; set; }
public IImplementationTypeSelector WithSingletonLifetime()
{
@@ -37,11 +37,17 @@ public IImplementationTypeSelector WithTransientLifetime()
{
return WithLifetime(ServiceLifetime.Transient);
}
-
public IImplementationTypeSelector WithLifetime(ServiceLifetime lifetime)
{
Preconditions.IsDefined(lifetime, nameof(lifetime));
+ return WithLifetime(_ => lifetime);
+ }
+
+ public IImplementationTypeSelector WithLifetime(Func lifetime)
+ {
+ Preconditions.NotNull(lifetime, nameof(lifetime));
+
Inner.PropagateLifetime(lifetime);
return this;
@@ -205,7 +211,7 @@ void ISelector.Populate(IServiceCollection services, RegistrationStrategy? strat
{
strategy ??= RegistrationStrategy.Append;
- var lifetime = Lifetime ?? ServiceLifetime.Transient;
+ var serviceLifetimes = new Dictionary();
foreach (var typeMap in TypeMaps)
{
@@ -218,7 +224,7 @@ void ISelector.Populate(IServiceCollection services, RegistrationStrategy? strat
throw new InvalidOperationException($@"Type ""{implementationType.ToFriendlyName()}"" is not assignable to ""${serviceType.ToFriendlyName()}"".");
}
- var descriptor = new ServiceDescriptor(serviceType, implementationType, lifetime);
+ var descriptor = new ServiceDescriptor(serviceType, implementationType, GetOrAddLifetime(serviceLifetimes, implementationType));
strategy.Apply(services, descriptor);
}
@@ -228,10 +234,17 @@ void ISelector.Populate(IServiceCollection services, RegistrationStrategy? strat
{
foreach (var serviceType in typeFactoryMap.ServiceTypes)
{
- var descriptor = new ServiceDescriptor(serviceType, typeFactoryMap.ImplementationFactory, lifetime);
+ var descriptor = new ServiceDescriptor(serviceType, typeFactoryMap.ImplementationFactory, GetOrAddLifetime(serviceLifetimes, typeFactoryMap.ImplementationType));
strategy.Apply(services, descriptor);
}
}
}
+
+ private ServiceLifetime GetOrAddLifetime(Dictionary serviceLifetimes, Type implementationType)
+ {
+ return serviceLifetimes.TryGetValue(implementationType, out var lifetime)
+ ? lifetime
+ : (serviceLifetimes[implementationType] = Lifetime?.Invoke(implementationType) ?? ServiceLifetime.Transient);
+ }
}
diff --git a/src/Scrutor/ServiceTypeSelector.cs b/src/Scrutor/ServiceTypeSelector.cs
index c850d5e9..51ca8320 100644
--- a/src/Scrutor/ServiceTypeSelector.cs
+++ b/src/Scrutor/ServiceTypeSelector.cs
@@ -71,7 +71,7 @@ public ILifetimeSelector AsSelfWithInterfaces(Func predicate)
return AddSelector(
Types.Select(t => new TypeMap(t, new[] { t })),
- Types.Select(t => new TypeFactoryMap(x => x.GetRequiredService(t), Selector(t, predicate))));
+ Types.Select(t => new TypeFactoryMap(x => x.GetRequiredService(t), Selector(t, predicate), t)));
static IEnumerable Selector(Type type, Func predicate)
{
@@ -209,7 +209,7 @@ public IServiceTypeSelector AddClasses(Action action,
#endregion
- internal void PropagateLifetime(ServiceLifetime lifetime)
+ internal void PropagateLifetime(Func lifetime)
{
foreach (var selector in Selectors.OfType())
{
diff --git a/src/Scrutor/TypeFactoryMap.cs b/src/Scrutor/TypeFactoryMap.cs
index d26e0273..f2c5edc2 100644
--- a/src/Scrutor/TypeFactoryMap.cs
+++ b/src/Scrutor/TypeFactoryMap.cs
@@ -5,13 +5,17 @@ namespace Scrutor;
internal struct TypeFactoryMap
{
- public TypeFactoryMap(Func implementationFactory, IEnumerable serviceTypes)
+ public TypeFactoryMap(Func implementationFactory, IEnumerable serviceTypes, Type implementationType)
{
ImplementationFactory = implementationFactory;
ServiceTypes = serviceTypes;
+ ImplementationType = implementationType;
}
public Func ImplementationFactory { get; }
public IEnumerable ServiceTypes { get; }
+
+ public Type ImplementationType { get; }
+
}