diff --git a/src/Scrutor/ILifetimeSelector.cs b/src/Scrutor/ILifetimeSelector.cs index ba7771a2..d473110b 100644 --- a/src/Scrutor/ILifetimeSelector.cs +++ b/src/Scrutor/ILifetimeSelector.cs @@ -26,7 +26,7 @@ public interface ILifetimeSelector : IServiceTypeSelector IImplementationTypeSelector WithLifetime(ServiceLifetime lifetime); /// - /// Registers each matching concrete type with the specified . + /// Registers each matching concrete type with a lifetime based on the provided . /// - IImplementationTypeSelector WithLifetime(Func lifetime); + IImplementationTypeSelector WithLifetime(Func selector); } diff --git a/src/Scrutor/LifetimeSelector.cs b/src/Scrutor/LifetimeSelector.cs index 0c224902..a6a222ef 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 Func? Lifetime { get; set; } + public Func? SelectorFn { get; set; } public IImplementationTypeSelector WithSingletonLifetime() { @@ -44,11 +44,11 @@ public IImplementationTypeSelector WithLifetime(ServiceLifetime lifetime) return WithLifetime(_ => lifetime); } - public IImplementationTypeSelector WithLifetime(Func lifetime) + public IImplementationTypeSelector WithLifetime(Func selector) { - Preconditions.NotNull(lifetime, nameof(lifetime)); + Preconditions.NotNull(selector, nameof(selector)); - Inner.PropagateLifetime(lifetime); + Inner.PropagateLifetime(selector); return this; } @@ -211,7 +211,7 @@ void ISelector.Populate(IServiceCollection services, RegistrationStrategy? strat { strategy ??= RegistrationStrategy.Append; - var serviceLifetimes = new Dictionary(); + var lifetimes = new Dictionary(); foreach (var typeMap in TypeMaps) { @@ -224,7 +224,9 @@ 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, GetOrAddLifetime(serviceLifetimes, implementationType)); + var lifetime = GetOrAddLifetime(lifetimes, implementationType); + + var descriptor = new ServiceDescriptor(serviceType, implementationType, lifetime); strategy.Apply(services, descriptor); } @@ -234,17 +236,26 @@ void ISelector.Populate(IServiceCollection services, RegistrationStrategy? strat { foreach (var serviceType in typeFactoryMap.ServiceTypes) { - var descriptor = new ServiceDescriptor(serviceType, typeFactoryMap.ImplementationFactory, GetOrAddLifetime(serviceLifetimes, typeFactoryMap.ImplementationType)); + var lifetime = GetOrAddLifetime(lifetimes, typeFactoryMap.ImplementationType); + + var descriptor = new ServiceDescriptor(serviceType, typeFactoryMap.ImplementationFactory, lifetime); strategy.Apply(services, descriptor); } } } - private ServiceLifetime GetOrAddLifetime(Dictionary serviceLifetimes, Type implementationType) + private ServiceLifetime GetOrAddLifetime(Dictionary lifetimes, Type implementationType) { - return serviceLifetimes.TryGetValue(implementationType, out var lifetime) - ? lifetime - : (serviceLifetimes[implementationType] = Lifetime?.Invoke(implementationType) ?? ServiceLifetime.Transient); + if (lifetimes.TryGetValue(implementationType, out var lifetime)) + { + return lifetime; + } + + lifetime = SelectorFn?.Invoke(implementationType) ?? ServiceLifetime.Transient; + + lifetimes[implementationType] = lifetime; + + return lifetime; } } diff --git a/src/Scrutor/ServiceCollectionExtensions.Decoration.cs b/src/Scrutor/ServiceCollectionExtensions.Decoration.cs index a588beb8..189ffad7 100644 --- a/src/Scrutor/ServiceCollectionExtensions.Decoration.cs +++ b/src/Scrutor/ServiceCollectionExtensions.Decoration.cs @@ -281,7 +281,7 @@ public static bool TryDecorate(this IServiceCollection services, DecorationStrat /// The service descriptor. public static bool IsDecorated(this ServiceDescriptor descriptor) => descriptor.ServiceKey is string stringKey - && stringKey.EndsWith(DecoratedServiceKeySuffix, StringComparison.Ordinal); + && stringKey.EndsWith(DecoratedServiceKeySuffix, StringComparison.Ordinal); private static string? GetDecoratorKey(ServiceDescriptor descriptor) { diff --git a/src/Scrutor/ServiceTypeSelector.cs b/src/Scrutor/ServiceTypeSelector.cs index 51ca8320..0637d6e7 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), t))); + Types.Select(t => new TypeFactoryMap(t, x => x.GetRequiredService(t), Selector(t, predicate)))); static IEnumerable Selector(Type type, Func predicate) { @@ -209,11 +209,11 @@ public IServiceTypeSelector AddClasses(Action action, #endregion - internal void PropagateLifetime(Func lifetime) + internal void PropagateLifetime(Func selectorFn) { foreach (var selector in Selectors.OfType()) { - selector.Lifetime = lifetime; + selector.SelectorFn = selectorFn; } } diff --git a/src/Scrutor/TypeFactoryMap.cs b/src/Scrutor/TypeFactoryMap.cs index f2c5edc2..2158275c 100644 --- a/src/Scrutor/TypeFactoryMap.cs +++ b/src/Scrutor/TypeFactoryMap.cs @@ -5,17 +5,16 @@ namespace Scrutor; internal struct TypeFactoryMap { - public TypeFactoryMap(Func implementationFactory, IEnumerable serviceTypes, Type implementationType) + public TypeFactoryMap(Type implementationType, Func implementationFactory, IEnumerable serviceTypes) { + ImplementationType = implementationType; ImplementationFactory = implementationFactory; ServiceTypes = serviceTypes; - ImplementationType = implementationType; } + public Type ImplementationType { get; } + public Func ImplementationFactory { get; } public IEnumerable ServiceTypes { get; } - - public Type ImplementationType { get; } - }