@@ -11,7 +11,7 @@ namespace Microsoft.Extensions.DependencyInjection.Specification
11
11
{
12
12
public abstract partial class KeyedDependencyInjectionSpecificationTests
13
13
{
14
- protected abstract IServiceProvider CreateServiceProvider ( IServiceCollection collection ) ;
14
+ protected abstract IServiceProvider CreateServiceProvider ( IServiceCollection collection ) ;
15
15
16
16
[ Fact ]
17
17
public void ResolveKeyedService ( )
@@ -263,6 +263,70 @@ public void ResolveKeyedServiceSingletonInstanceWithKeyedParameter()
263
263
Assert . Equal ( "service2" , svc . Service2 . ToString ( ) ) ;
264
264
}
265
265
266
+ [ Fact ]
267
+ public void ResolveKeyedServiceWithKeyedParameter_MissingRegistration_SecondParameter ( )
268
+ {
269
+ var serviceCollection = new ServiceCollection ( ) ;
270
+
271
+ serviceCollection . AddKeyedSingleton < IService , Service > ( "service1" ) ;
272
+ // We are missing the registration for "service2" here and OtherService requires it.
273
+
274
+ serviceCollection . AddSingleton < OtherService > ( ) ;
275
+
276
+ var provider = CreateServiceProvider ( serviceCollection ) ;
277
+
278
+ Assert . Null ( provider . GetService < IService > ( ) ) ;
279
+ Assert . Throws < InvalidOperationException > ( ( ) => provider . GetService < OtherService > ( ) ) ;
280
+ }
281
+
282
+ [ Fact ]
283
+ public void ResolveKeyedServiceWithKeyedParameter_MissingRegistration_FirstParameter ( )
284
+ {
285
+ var serviceCollection = new ServiceCollection ( ) ;
286
+
287
+ // We are not registering "service1" and "service1" keyed IService services and OtherService requires them.
288
+
289
+ serviceCollection . AddSingleton < OtherService > ( ) ;
290
+
291
+ var provider = CreateServiceProvider ( serviceCollection ) ;
292
+
293
+ Assert . Null ( provider . GetService < IService > ( ) ) ;
294
+ Assert . Throws < InvalidOperationException > ( ( ) => provider . GetService < OtherService > ( ) ) ;
295
+ }
296
+
297
+ [ Fact ]
298
+ public void ResolveKeyedServiceWithKeyedParameter_MissingRegistrationButWithDefaults ( )
299
+ {
300
+ var serviceCollection = new ServiceCollection ( ) ;
301
+
302
+ // We are not registering "service1" and "service1" keyed IService services and OtherServiceWithDefaultCtorArgs
303
+ // specifies them but has argument defaults if missing.
304
+
305
+ serviceCollection . AddSingleton < OtherServiceWithDefaultCtorArgs > ( ) ;
306
+
307
+ var provider = CreateServiceProvider ( serviceCollection ) ;
308
+
309
+ Assert . Null ( provider . GetService < IService > ( ) ) ;
310
+ Assert . NotNull ( provider . GetService < OtherServiceWithDefaultCtorArgs > ( ) ) ;
311
+ }
312
+
313
+ [ Fact ]
314
+ public void ResolveKeyedServiceWithKeyedParameter_MissingRegistrationButWithUnkeyedService ( )
315
+ {
316
+ var serviceCollection = new ServiceCollection ( ) ;
317
+
318
+ // We are not registering "service1" and "service1" keyed IService services and OtherService requires them,
319
+ // but we are registering an unkeyed IService service which should not be injected into OtherService.
320
+ serviceCollection . AddSingleton < IService , Service > ( ) ;
321
+
322
+ serviceCollection . AddSingleton < OtherService > ( ) ;
323
+
324
+ var provider = CreateServiceProvider ( serviceCollection ) ;
325
+
326
+ Assert . NotNull ( provider . GetService < IService > ( ) ) ;
327
+ Assert . Throws < InvalidOperationException > ( ( ) => provider . GetService < OtherService > ( ) ) ;
328
+ }
329
+
266
330
[ Fact ]
267
331
public void CreateServiceWithKeyedParameter ( )
268
332
{
@@ -490,9 +554,9 @@ public void ResolveKeyedTransientFromScopeServiceProvider()
490
554
Assert . NotSame ( serviceA1 , serviceB1 ) ;
491
555
}
492
556
493
- internal interface IService { }
557
+ public interface IService { }
494
558
495
- internal class Service : IService
559
+ public class Service : IService
496
560
{
497
561
private readonly string _id ;
498
562
@@ -503,7 +567,7 @@ internal class Service : IService
503
567
public override string ? ToString ( ) => _id ;
504
568
}
505
569
506
- internal class OtherService
570
+ public class OtherService
507
571
{
508
572
public OtherService (
509
573
[ FromKeyedServices ( "service1" ) ] IService service1 ,
@@ -518,6 +582,36 @@ public OtherService(
518
582
public IService Service2 { get ; }
519
583
}
520
584
585
+ internal class OtherServiceWithDefaultCtorArgs
586
+ {
587
+ public OtherServiceWithDefaultCtorArgs (
588
+ [ FromKeyedServices ( "service1" ) ] IService service1 = null ,
589
+ [ FromKeyedServices ( "service2" ) ] IService service2 = null )
590
+ {
591
+ Service1 = service1 ;
592
+ Service2 = service2 ;
593
+ }
594
+
595
+ public IService Service1 { get ; }
596
+
597
+ public IService Service2 { get ; }
598
+ }
599
+
600
+ internal class ServiceWithOtherService
601
+ {
602
+ public ServiceWithOtherService (
603
+ [ FromKeyedServices ( "service1" ) ] IService service1 ,
604
+ [ FromKeyedServices ( "service2" ) ] IService service2 )
605
+ {
606
+ Service1 = service1 ;
607
+ Service2 = service2 ;
608
+ }
609
+
610
+ public IService Service1 { get ; }
611
+
612
+ public IService Service2 { get ; }
613
+ }
614
+
521
615
internal class ServiceWithIntKey : IService
522
616
{
523
617
private readonly int _id ;
0 commit comments