22using System . Reflection ;
33using Castle . DynamicProxy ;
44using Eocron . DependencyInjection . Interceptors . Caching ;
5+ using Eocron . DependencyInjection . Interceptors . Locking ;
56using Eocron . DependencyInjection . Interceptors . Logging ;
67using Eocron . DependencyInjection . Interceptors . Retry ;
78using Eocron . DependencyInjection . Interceptors . Timeout ;
@@ -16,20 +17,49 @@ public static class DecoratorChainExtensions
1617 public static DecoratorChain AddInterceptor ( this DecoratorChain decoratorChain ,
1718 Func < IServiceProvider , IAsyncInterceptor > interceptorFactory )
1819 {
19- decoratorChain . Add ( ( sp , instance ) => InterceptionHelper . CreateProxy ( instance , interceptorFactory ( sp ) ) ) ;
20+ decoratorChain . Add ( ( sp , keyPrefix , instance , lifetime ) => InterceptionHelper . CreateProxy ( decoratorChain . ServiceType , instance , interceptorFactory ( sp ) ) ) ;
2021 return decoratorChain ;
2122 }
2223
2324 public static DecoratorChain AddInterceptor ( this DecoratorChain decoratorChain ,
24- IAsyncInterceptor interceptor )
25+ Func < IServiceProvider , string , ServiceLifetime , IAsyncInterceptor > interceptorFactory ,
26+ DecoratorConfiguratorDelegate interceptorConfigurator )
2527 {
26- decoratorChain . Add ( ( sp , instance ) => InterceptionHelper . CreateProxy ( instance , interceptor ) ) ;
28+ decoratorChain . Add ( ( sp , keyPrefix , instance , lifetime ) => InterceptionHelper . CreateProxy ( decoratorChain . ServiceType , instance , interceptorFactory ( sp , keyPrefix , lifetime ) ) , interceptorConfigurator ) ;
2729 return decoratorChain ;
2830 }
2931
30- public static DecoratorChain AddTracing ( this DecoratorChain decoratorChain )
32+ public static DecoratorChain AddLock ( this DecoratorChain decoratorChain ,
33+ Func < IServiceProvider , ILockProvider > lockProvider )
34+ {
35+ decoratorChain . AddInterceptor ( sp =>
36+ new LockAsyncInterceptor (
37+ lockProvider ( sp ) ,
38+ false ) ) ;
39+ return decoratorChain ;
40+ }
41+
42+ public static DecoratorChain AddSemaphoreSlimLock ( this DecoratorChain decoratorChain , int initialCount = 1 )
43+ {
44+ decoratorChain . AddInterceptor ( ( sp , keyPrefix , lifetime ) =>
45+ new LockAsyncInterceptor ( sp . GetRequiredKeyedService < ILockProvider > ( keyPrefix ) , lifetime == ServiceLifetime . Transient ) ,
46+ ( services , keyPrefix , lifetime ) =>
47+ {
48+ services . Add ( new ServiceDescriptor ( typeof ( ILockProvider ) , keyPrefix , ( _ , _ ) => new SemaphoreSlimLockProvider ( initialCount ) , lifetime ) ) ;
49+ } ) ;
50+ return decoratorChain ;
51+ }
52+
53+ public static DecoratorChain AddMonitorLock ( this DecoratorChain decoratorChain )
3154 {
3255 decoratorChain . AddInterceptor ( ( sp ) =>
56+ new LockAsyncInterceptor ( new MonitorLockProvider ( ) , false ) ) ;
57+ return decoratorChain ;
58+ }
59+
60+ public static DecoratorChain AddTracing ( this DecoratorChain decoratorChain )
61+ {
62+ decoratorChain . AddInterceptor ( sp =>
3363 new LoggingAsyncInterceptor (
3464 sp . GetService < ILoggerFactory > ( ) . CreateLogger ( decoratorChain . ServiceType . FullName ) ,
3565 LogLevel . Trace ,
@@ -44,15 +74,15 @@ public static DecoratorChain AddTimeout(this DecoratorChain decoratorChain, Time
4474 return decoratorChain ;
4575 }
4676
47- decoratorChain . AddInterceptor ( new TimeoutAsyncInterceptor ( timeout ) ) ;
77+ decoratorChain . AddInterceptor ( _ => new TimeoutAsyncInterceptor ( timeout ) ) ;
4878 return decoratorChain ;
4979 }
5080
5181 public static DecoratorChain AddRetry ( this DecoratorChain decoratorChain ,
5282 Func < int , Exception , bool > exceptionPredicate ,
5383 Func < int , Exception , TimeSpan > retryIntervalProvider )
5484 {
55- decoratorChain . AddInterceptor ( ( sp ) => new RetryUntilConditionAsyncInterceptor ( exceptionPredicate ,
85+ decoratorChain . AddInterceptor ( sp => new RetryAsyncInterceptor ( exceptionPredicate ,
5686 retryIntervalProvider ,
5787 sp . GetService < ILoggerFactory > ( ) ? . CreateLogger ( decoratorChain . ServiceType . Name ) ) ) ;
5888 return decoratorChain ;
@@ -66,7 +96,7 @@ public static DecoratorChain AddConstantBackoff(this DecoratorChain decoratorCha
6696 {
6797 return decoratorChain . AddRetry (
6898 ( c , ex ) => c <= maxAttempts && ( isRetryable ? . Invoke ( ex ) ?? true ) ,
69- ( c , _ ) => ConstantBackoff . Calculate ( StaticRandom . Value , retryInterval , jittered ) ) ;
99+ ( _ , _ ) => ConstantBackoff . Calculate ( StaticRandom . Value , retryInterval , jittered ) ) ;
70100 }
71101
72102 public static DecoratorChain AddExponentialBackoff ( this DecoratorChain decoratorChain ,
@@ -81,27 +111,36 @@ public static DecoratorChain AddExponentialBackoff(this DecoratorChain decorator
81111 ( c , _ ) => CorrelatedExponentialBackoff . Calculate ( StaticRandom . Value , c , minPropagationDuration , maxPropagationDuration , jittered ) ) ;
82112 }
83113
114+ public static DecoratorChain AddCache ( this DecoratorChain decoratorChain ,
115+ Func < MethodInfo , object [ ] , object > keyProvider )
116+ {
117+ decoratorChain . AddInterceptor ( sp => new MemoryCacheAsyncInterceptor ( sp . GetRequiredService < IMemoryCache > ( ) ,
118+ keyProvider ,
119+ ( _ , _ , _ ) => { } ) ) ;
120+ return decoratorChain ;
121+ }
122+
84123 public static DecoratorChain AddSlidingTimeoutCache ( this DecoratorChain decoratorChain ,
85- Func < MethodInfo , object [ ] , object > keyProvider ,
86- TimeSpan cacheDuration )
124+ TimeSpan cacheDuration ,
125+ Func < MethodInfo , object [ ] , object > keyProvider )
87126 {
88127 if ( cacheDuration <= TimeSpan . Zero )
89128 return decoratorChain ;
90129
91- decoratorChain . AddInterceptor ( ( sp ) => new MemoryCacheAsyncInterceptor ( sp . GetRequiredService < IMemoryCache > ( ) ,
130+ decoratorChain . AddInterceptor ( sp => new MemoryCacheAsyncInterceptor ( sp . GetRequiredService < IMemoryCache > ( ) ,
92131 keyProvider ,
93132 ( _ , _ , ce ) => ce . SetSlidingExpiration ( cacheDuration ) ) ) ;
94133 return decoratorChain ;
95134 }
96135
97- public static DecoratorChain AddTimeoutCache ( this DecoratorChain decoratorChain ,
98- Func < MethodInfo , object [ ] , object > keyProvider ,
99- TimeSpan cacheDuration )
136+ public static DecoratorChain AddAbsoluteTimeoutCache ( this DecoratorChain decoratorChain ,
137+ TimeSpan cacheDuration ,
138+ Func < MethodInfo , object [ ] , object > keyProvider )
100139 {
101140 if ( cacheDuration <= TimeSpan . Zero )
102141 return decoratorChain ;
103142
104- decoratorChain . AddInterceptor ( ( sp ) => new MemoryCacheAsyncInterceptor ( sp . GetRequiredService < IMemoryCache > ( ) ,
143+ decoratorChain . AddInterceptor ( sp => new MemoryCacheAsyncInterceptor ( sp . GetRequiredService < IMemoryCache > ( ) ,
105144 keyProvider ,
106145 ( _ , _ , ce ) => ce . SetAbsoluteExpiration ( cacheDuration ) ) ) ;
107146 return decoratorChain ;
0 commit comments