@@ -17,6 +17,11 @@ internal static ServiceCallSite GetCallSite(this CallSiteFactory callSiteFactory
17
17
{
18
18
return callSiteFactory . GetCallSite ( ServiceIdentifier . FromServiceType ( type ) , callSiteChain ) ;
19
19
}
20
+
21
+ internal static ServiceCallSite GetKeyedCallSite ( this CallSiteFactory callSiteFactory , Type type , object ? serviceKey , CallSiteChain callSiteChain )
22
+ {
23
+ return callSiteFactory . GetCallSite ( new ServiceIdentifier ( serviceKey , type ) , callSiteChain ) ;
24
+ }
20
25
}
21
26
22
27
public class CallSiteTests
@@ -300,6 +305,61 @@ public void CallSiteFactoryResolvesIEnumerableOfOpenGenericServiceAfterResolving
300
305
Assert . Equal ( typeof ( FakeOpenGenericService < int > ) , implementationTypes [ 1 ] ) ;
301
306
}
302
307
308
+ [ Fact ]
309
+ public void ServiceCallSite_ShouldHaveKey_WhenResolvingKeyedService ( )
310
+ {
311
+ // Arrange
312
+ IServiceCollection services = new ServiceCollection ( ) ;
313
+
314
+ services . Add ( ServiceDescriptor . Transient ( typeof ( SomeService ) , typeof ( SomeService ) ) ) ;
315
+ services . Add ( ServiceDescriptor . KeyedTransient ( typeof ( SomeService ) , "someKey" , typeof ( SomeOtherService ) ) ) ;
316
+
317
+ using var serviceProvider = services . BuildServiceProvider ( ) ;
318
+
319
+ // Act
320
+ var callSite = serviceProvider . CallSiteFactory . GetKeyedCallSite ( typeof ( SomeService ) , "someKey" , new CallSiteChain ( ) ) ;
321
+
322
+ // Assert
323
+ Assert . NotNull ( callSite . Key ) ;
324
+ }
325
+
326
+ [ Fact ]
327
+ public void ServiceCallSite_ShouldHaveKey_WhenResolvingKeyedClosedImplementationOfOpenGenericService ( )
328
+ {
329
+ // Arrange
330
+ IServiceCollection services = new ServiceCollection ( ) ;
331
+
332
+ services . Add ( ServiceDescriptor . Transient ( typeof ( IGenericService < > ) , typeof ( UnkeyedGenericService < > ) ) ) ;
333
+ services . Add ( ServiceDescriptor . KeyedTransient ( typeof ( IGenericService < > ) , "someKey" , typeof ( PrimaryKeyedGenericService < > ) ) ) ;
334
+
335
+ using var serviceProvider = services . BuildServiceProvider ( ) ;
336
+
337
+ // Act
338
+ var callSite = serviceProvider . CallSiteFactory . GetKeyedCallSite ( typeof ( IGenericService < object > ) , "someKey" , new CallSiteChain ( ) ) ;
339
+
340
+ // Assert
341
+ Assert . NotNull ( callSite . Key ) ;
342
+ }
343
+
344
+ [ Fact ]
345
+ public void ServiceCallSite_ShouldHaveKey_WhenResolvingKeyedIEnumerableOfClosedImplementationOfOpenGenericService ( )
346
+ {
347
+ // Arrange
348
+ IServiceCollection services = new ServiceCollection ( ) ;
349
+
350
+ services . Add ( ServiceDescriptor . Transient ( typeof ( IGenericService < > ) , typeof ( UnkeyedGenericService < > ) ) ) ;
351
+ services . Add ( ServiceDescriptor . KeyedTransient ( typeof ( IGenericService < > ) , "someKey" , typeof ( PrimaryKeyedGenericService < > ) ) ) ;
352
+ services . Add ( ServiceDescriptor . KeyedTransient ( typeof ( IGenericService < > ) , "someKey" , typeof ( SecondaryKeyedGenericService < > ) ) ) ;
353
+
354
+ using var serviceProvider = services . BuildServiceProvider ( ) ;
355
+
356
+ // Act
357
+ var callSite = serviceProvider . CallSiteFactory . GetKeyedCallSite ( typeof ( IEnumerable < IGenericService < object > > ) , "someKey" , new CallSiteChain ( ) ) ;
358
+
359
+ // Assert
360
+ Assert . NotNull ( callSite . Key ) ;
361
+ }
362
+
303
363
private class FakeIntService : IFakeOpenGenericService < int >
304
364
{
305
365
public int Value => 0 ;
@@ -395,6 +455,18 @@ public void Dispose()
395
455
}
396
456
}
397
457
458
+ private interface IGenericService < T > ;
459
+
460
+ private class UnkeyedGenericService< T > : IGenericService < T > ;
461
+
462
+ private class PrimaryKeyedGenericService < T > : IGenericService < T > ;
463
+
464
+ private class SecondaryKeyedGenericService < T > : IGenericService < T > ;
465
+
466
+ private class SomeService;
467
+
468
+ private class SomeOtherService : SomeService ;
469
+
398
470
private static object Invoke( ServiceCallSite callSite , ServiceProviderEngineScope scope )
399
471
{
400
472
return CallSiteRuntimeResolver . Instance . Resolve ( callSite , scope ) ;
0 commit comments