@@ -336,6 +336,61 @@ public async Task Can_use_custom_cache_implementation()
336336 replacementCache . SetCount . ShouldBe ( 1 ) ;
337337 }
338338
339+ [ Fact ]
340+ public async Task Can_use_custom_cache_implementation_only_for_DistributedClientCredentialsTokenCache ( )
341+ {
342+ var services = new ServiceCollection ( ) ;
343+
344+ services . AddDistributedMemoryCache ( ) ;
345+ var replacementCache = new FakeCache ( ) ;
346+
347+ // register the cache, but using a different key (not default 'duende')
348+ services . AddKeyedSingleton < IDistributedCache > ( "different" , replacementCache )
349+
350+ // Now register a custom OptionallyKeyedDependency that uses the different key
351+ . AddKeyedTransient < OptionallyKeyedDependency < IDistributedCache > ,
352+ CustomOptionallyKeyedDependency < IDistributedCache > > ( nameof ( DistributedClientCredentialsTokenCache ) ) ;
353+
354+ services . AddClientCredentialsTokenManagement ( )
355+ . AddClient ( "test" , client =>
356+ {
357+ client . TokenEndpoint = "https://as" ;
358+ client . ClientId = "id" ;
359+
360+ client . HttpClientName = "custom" ;
361+ } ) ;
362+
363+ var mockHttp = new MockHttpMessageHandler ( ) ;
364+ mockHttp . When ( "https://as/*" )
365+ . Respond ( HttpStatusCode . OK , JsonContent . Create ( new TokenResponse ( ) ) ) ;
366+
367+ services . AddHttpClient ( "custom" )
368+ . ConfigurePrimaryHttpMessageHandler ( ( ) => mockHttp ) ;
369+
370+ var provider = services . BuildServiceProvider ( ) ;
371+ var sut = provider . GetRequiredService < IClientCredentialsTokenManagementService > ( ) ;
372+
373+ var token = await sut . GetAccessTokenAsync ( "test" ) ;
374+
375+ token . Error . ShouldBeNull ( ) ;
376+
377+ // Verify we actually used the cache
378+ replacementCache . GetCount . ShouldBe ( 1 ) ;
379+ replacementCache . SetCount . ShouldBe ( 1 ) ;
380+ }
381+
382+ /// <summary>
383+ /// You can change the key of a dependency by deriving from OptionallyKeyedDependency.
384+ /// </summary>
385+ /// <typeparam name="T"></typeparam>
386+ public class CustomOptionallyKeyedDependency < T > (
387+ T defaultDependency ,
388+
389+ // Here the key is overwritten
390+ [ FromKeyedServices ( ( "different" ) ) ] T ? keyedDependency = default ( T ? ) )
391+ : OptionallyKeyedDependency < T > ( defaultDependency , keyedDependency )
392+ where T : class ;
393+
339394 public class FakeCache : IDistributedCache
340395 {
341396 public int GetCount = 0 ;
@@ -346,18 +401,18 @@ public class FakeCache : IDistributedCache
346401 throw new InvalidOperationException ( ) ;
347402 }
348403
349- public async Task < byte [ ] ? > GetAsync ( string key , CancellationToken token = new CancellationToken ( ) )
404+ public Task < byte [ ] ? > GetAsync ( string key , CancellationToken token = new CancellationToken ( ) )
350405 {
351406 Interlocked . Increment ( ref GetCount ) ;
352- return null ;
407+ return Task . FromResult < byte [ ] ? > ( null ) ;
353408 }
354409
355410 public void Refresh ( string key )
356411 {
357412 throw new InvalidOperationException ( ) ;
358413 }
359414
360- public async Task RefreshAsync ( string key , CancellationToken token = new CancellationToken ( ) )
415+ public Task RefreshAsync ( string key , CancellationToken token = new CancellationToken ( ) )
361416 {
362417 throw new InvalidOperationException ( ) ;
363418 }
@@ -367,7 +422,7 @@ public void Remove(string key)
367422 throw new InvalidOperationException ( ) ;
368423 }
369424
370- public async Task RemoveAsync ( string key , CancellationToken token = new CancellationToken ( ) )
425+ public Task RemoveAsync ( string key , CancellationToken token = new CancellationToken ( ) )
371426 {
372427 throw new InvalidOperationException ( ) ;
373428 }
@@ -377,10 +432,11 @@ public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
377432 throw new InvalidOperationException ( ) ;
378433 }
379434
380- public async Task SetAsync ( string key , byte [ ] value , DistributedCacheEntryOptions options ,
435+ public Task SetAsync ( string key , byte [ ] value , DistributedCacheEntryOptions options ,
381436 CancellationToken token = new CancellationToken ( ) )
382437 {
383438 Interlocked . Increment ( ref SetCount ) ;
439+ return Task . CompletedTask ;
384440 }
385441 }
386442}
0 commit comments