| | | 1 | | namespace NexusLabs.Needlr.Injection.TypeFilterers; |
| | | 2 | | |
| | | 3 | | /// <summary> |
| | | 4 | | /// A decorator that wraps an <see cref="ITypeFilterer"/> and modifies its filtering behavior. |
| | | 5 | | /// Allows customization of lifetime categorization without replacing the entire filterer. |
| | | 6 | | /// </summary> |
| | | 7 | | public sealed class TypeFilterDecorator : ITypeFilterer |
| | | 8 | | { |
| | | 9 | | private readonly ITypeFilterer _innerFilterer; |
| | | 10 | | private readonly Func<Predicate<Type>, Type, bool> _scopedTypeFilterer; |
| | | 11 | | private readonly Func<Predicate<Type>, Type, bool> _transientTypeFilter; |
| | | 12 | | private readonly Func<Predicate<Type>, Type, bool> _singletonTypeFilter; |
| | | 13 | | private readonly Predicate<Type>? _exclusionPredicate; |
| | | 14 | | |
| | 75 | 15 | | public TypeFilterDecorator( |
| | 75 | 16 | | ITypeFilterer innerFilterer, |
| | 75 | 17 | | Func<Predicate<Type>, Type, bool> scopedTypeFilterer, |
| | 75 | 18 | | Func<Predicate<Type>, Type, bool> transientTypeFilterer, |
| | 75 | 19 | | Func<Predicate<Type>, Type, bool> singletonTypeFilter, |
| | 75 | 20 | | Predicate<Type>? exclusionPredicate = null) |
| | | 21 | | { |
| | 75 | 22 | | ArgumentNullException.ThrowIfNull(innerFilterer); |
| | 75 | 23 | | ArgumentNullException.ThrowIfNull(scopedTypeFilterer); |
| | 75 | 24 | | ArgumentNullException.ThrowIfNull(transientTypeFilterer); |
| | 75 | 25 | | ArgumentNullException.ThrowIfNull(singletonTypeFilter); |
| | | 26 | | |
| | 75 | 27 | | _innerFilterer = innerFilterer; |
| | 75 | 28 | | _scopedTypeFilterer = scopedTypeFilterer; |
| | 75 | 29 | | _transientTypeFilter = transientTypeFilterer; |
| | 75 | 30 | | _singletonTypeFilter = singletonTypeFilter; |
| | 75 | 31 | | _exclusionPredicate = exclusionPredicate; |
| | 75 | 32 | | } |
| | | 33 | | |
| | | 34 | | /// <inheritdoc /> |
| | | 35 | | public bool IsInjectableScopedType(Type type) |
| | 4461 | 36 | | => _scopedTypeFilterer.Invoke( |
| | 4461 | 37 | | _innerFilterer.IsInjectableScopedType, |
| | 4461 | 38 | | type); |
| | | 39 | | |
| | | 40 | | /// <inheritdoc /> |
| | | 41 | | public bool IsInjectableTransientType(Type type) |
| | 4515 | 42 | | => _transientTypeFilter.Invoke( |
| | 4515 | 43 | | _innerFilterer.IsInjectableTransientType, |
| | 4515 | 44 | | type); |
| | | 45 | | |
| | | 46 | | /// <inheritdoc /> |
| | | 47 | | public bool IsInjectableSingletonType(Type type) |
| | 6940 | 48 | | => _singletonTypeFilter.Invoke( |
| | 6940 | 49 | | _innerFilterer.IsInjectableSingletonType, |
| | 6940 | 50 | | type); |
| | | 51 | | |
| | | 52 | | /// <inheritdoc /> |
| | | 53 | | public bool IsTypeExcluded(Type type) |
| | | 54 | | { |
| | | 55 | | // Check our exclusion predicate first |
| | 6898 | 56 | | if (_exclusionPredicate?.Invoke(type) == true) |
| | | 57 | | { |
| | 50 | 58 | | return true; |
| | | 59 | | } |
| | | 60 | | |
| | | 61 | | // Delegate to inner filterer |
| | 6848 | 62 | | return _innerFilterer.IsTypeExcluded(type); |
| | | 63 | | } |
| | | 64 | | } |