/src/UnitTests/IOC/InversionOfControlTests.cs
C# | 735 lines | 520 code | 151 blank | 64 comment | 23 complexity | daad95bf8953aa3338cc36af743a2d4a MD5 | raw file
1using System; 2using System.Linq; 3using System.Runtime.Serialization; 4using LinFu.IoC; 5using LinFu.IoC.Configuration; 6using LinFu.IoC.Interfaces; 7using LinFu.Proxy; 8using LinFu.Proxy.Interfaces; 9using Moq; 10using Xunit; 11using SampleLibrary; 12using SampleLibrary.IOC; 13using SampleLibrary.IOC.BugFixes; 14 15namespace LinFu.UnitTests.IOC 16{ 17 public class InversionOfControlTests 18 { 19 private static void VerifyInitializeCall(ServiceContainer container, Mock<IInitialize> mockService) 20 { 21 container.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "*.dll"); 22 container.AddService(mockService.Object); 23 24 25 mockService.Expect(i => i.Initialize(container)).AtMostOnce(); 26 27 // The container should return the same instance 28 var firstResult = container.GetService<IInitialize>(); 29 var secondResult = container.GetService<IInitialize>(); 30 Assert.Same(firstResult, secondResult); 31 32 // The Initialize() method should only be called once 33 mockService.Verify(); 34 } 35 36 [Fact] 37 public void AroundInvokeClassesMarkedWithInterceptorAttributeMustGetActualTargetInstance() 38 { 39 var container = new ServiceContainer(); 40 container.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "*.dll"); 41 var mockService = new Mock<ISampleWrappedInterface>(); 42 mockService.Expect(mock => mock.DoSomething()); 43 44 // Add the target instance 45 container.AddService(mockService.Object); 46 47 // The service must return a proxy 48 var service = container.GetService<ISampleWrappedInterface>(); 49 Assert.NotSame(service, mockService.Object); 50 51 // Execute the method and 'catch' the target instance once the method call is made 52 service.DoSomething(); 53 54 var holder = container.GetService<ITargetHolder>("SampleAroundInvokeInterceptorClass"); 55 Assert.Same(holder.Target, mockService.Object); 56 } 57 58 [Fact] 59 public void ContainerMustAllowInjectingCustomFactoriesForNamedOpenGenericTypeDefinitions() 60 { 61 var container = new ServiceContainer(); 62 var factory = new SampleOpenGenericFactory(); 63 var serviceName = "MyService"; 64 65 container.AddFactory(serviceName, typeof(ISampleGenericService<>), factory); 66 67 // The container must report that it *can* create 68 // the generic service type 69 Assert.True(container.Contains(serviceName, typeof(ISampleGenericService<int>))); 70 71 var result = container.GetService<ISampleGenericService<int>>(serviceName); 72 73 Assert.NotNull(result); 74 Assert.True(result.GetType() == typeof(SampleGenericImplementation<int>)); 75 } 76 77 [Fact] 78 public void ContainerMustAllowInjectingCustomFactoriesForOpenGenericTypeDefinitions() 79 { 80 var container = new ServiceContainer(); 81 var factory = new SampleOpenGenericFactory(); 82 83 container.AddFactory(typeof(ISampleGenericService<>), factory); 84 85 // The container must report that it *can* create 86 // the generic service type 87 Assert.True(container.Contains(typeof(ISampleGenericService<int>))); 88 89 var result = container.GetService<ISampleGenericService<int>>(); 90 91 Assert.NotNull(result); 92 Assert.True(result.GetType() == typeof(SampleGenericImplementation<int>)); 93 } 94 95 [Fact] 96 public void ContainerMustAllowServicesToBeIntercepted() 97 { 98 var container = new ServiceContainer(); 99 container.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "*.dll"); 100 101 var mock = new Mock<ISampleInterceptedInterface>(); 102 var mockInstance = mock.Object; 103 container.AddService(mockInstance); 104 105 // The container must automatically load the interceptor 106 // from the sample assembly 107 var result = container.GetService<ISampleInterceptedInterface>(); 108 Assert.NotSame(mockInstance, result); 109 110 var proxy = (IProxy)result; 111 Assert.NotNull(proxy.Interceptor); 112 } 113 114 [Fact] 115 public void ContainerMustAllowServicesToBeInterceptedWithAnAroundInvokeInterceptor() 116 { 117 var container = new ServiceContainer(); 118 container.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "*.dll"); 119 120 var mock = new Mock<ISampleWrappedInterface>(); 121 var mockInstance = mock.Object; 122 container.AddService(mockInstance); 123 124 // The container must automatically load the IAroundInvoke 125 // from the sample assembly 126 var result = container.GetService<ISampleWrappedInterface>(); 127 Assert.NotSame(mockInstance, result); 128 129 var proxy = (IProxy)result; 130 Assert.NotNull(proxy.Interceptor); 131 } 132 133 [Fact] 134 public void ContainerMustAllowSurrogatesForNonExistentServiceInstances() 135 { 136 var container = new ServiceContainer(); 137 var mockService = new Mock<ISampleService>(); 138 var surrogate = mockService.Object; 139 container.Inject<ISampleService>().Using((f, arguments) => surrogate).OncePerRequest(); 140 141 var result = container.GetService<ISampleService>(); 142 Assert.NotNull(result); 143 Assert.Same(surrogate, result); 144 } 145 146 [Fact] 147 public void ContainerMustAllowUntypedOpenGenericTypeRegistration() 148 { 149 var serviceType = typeof(ISampleGenericService<>); 150 var implementingType = typeof(SampleGenericImplementation<>); 151 152 var container = new ServiceContainer(); 153 container.AddService(serviceType, implementingType); 154 155 var result = container.GetService<ISampleGenericService<long>>(); 156 Assert.NotNull(result); 157 } 158 159 [Fact] 160 public void ContainerMustAllowUntypedServiceRegistration() 161 { 162 var container = new ServiceContainer(); 163 container.AddService(typeof(ISampleService), typeof(SampleClass)); 164 165 var service = container.GetService<ISampleService>(); 166 Assert.NotNull(service); 167 } 168 169 [Fact] 170 public void ContainerMustBeAbleToAddExistingServiceInstances() 171 { 172 var container = new ServiceContainer(); 173 var mockService = new Mock<ISerializable>(); 174 container.AddService(mockService.Object); 175 176 var result = container.GetService<ISerializable>(); 177 Assert.Same(result, mockService.Object); 178 } 179 180 [Fact] 181 public void ContainerMustBeAbleToReturnAListOfServices() 182 { 183 var mockSampleService = new Mock<ISampleService>(); 184 var container = new ServiceContainer(); 185 186 // Add a bunch of dummy services 187 for (var i = 0; i < 10; i++) 188 { 189 var serviceName = string.Format("Service{0}", i + 1); 190 container.AddService(serviceName, mockSampleService.Object); 191 } 192 193 var services = container.GetServices<ISampleService>(); 194 Assert.True(services.Count() == 10); 195 196 // The resulting set of services 197 // must match the given service instance 198 foreach (var service in services) Assert.Same(mockSampleService.Object, service); 199 } 200 201 [Fact] 202 public void ContainerMustBeAbleToSuppressNamedServiceNotFoundErrors() 203 { 204 ExpectException<NamedServiceNotFoundException>(() => 205 { 206 var container = new ServiceContainer(); 207 var instance = container.GetService("MyService", typeof(ISerializable)); 208 Assert.Null(instance); 209 }); 210 } 211 212 [Fact] 213 public void ContainerMustBeAbleToSupressServiceNotFoundErrors() 214 { 215 var container = new ServiceContainer(); 216 container.SuppressErrors = true; 217 218 var instance = container.GetService(typeof(ISerializable)); 219 Assert.Null(instance); 220 } 221 222 [Fact] 223 public void ContainerMustCallIInitializeOnServicesCreatedFromCustomFactory() 224 { 225 var mockFactory = new Mock<IFactory>(); 226 var mockInitialize = new Mock<IInitialize>(); 227 228 mockFactory.Expect(f => f.CreateInstance(It.IsAny<IFactoryRequest>())) 229 .Returns(mockInitialize.Object); 230 231 // The IInitialize instance must be called once it 232 // leaves the custom factory 233 mockInitialize.Expect(i => i.Initialize(It.IsAny<IServiceContainer>())); 234 235 var container = new ServiceContainer(); 236 container.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "LinFu*.dll"); 237 container.AddFactory(typeof(IInitialize), mockFactory.Object); 238 239 var result = container.GetService<IInitialize>(); 240 241 mockFactory.VerifyAll(); 242 mockInitialize.VerifyAll(); 243 } 244 245 [Fact] 246 public void ContainerMustCallPostProcessorDuringARequest() 247 { 248 var mockPostProcessor = new Mock<IPostProcessor>(); 249 var container = new ServiceContainer(); 250 container.PostProcessors.Add(mockPostProcessor.Object); 251 252 mockPostProcessor.Expect(p => 253 p.PostProcess(It.Is<IServiceRequestResult>(result => result != null))); 254 255 container.SuppressErrors = true; 256 container.GetService<ISerializable>(); 257 258 mockPostProcessor.VerifyAll(); 259 } 260 261 [Fact] 262 public void ContainerMustGetMultipleServicesOfTheSameTypeInOneCall() 263 { 264 var container = new ServiceContainer(); 265 var mockServiceCount = 10; 266 267 // Add a set of dummy services 268 for (var i = 0; i < mockServiceCount; i++) 269 { 270 var mockService = new Mock<ISampleService>(); 271 container.AddService(string.Format("Service{0}", i + 1), mockService.Object); 272 } 273 274 var instances = container.GetServices<ISampleService>(); 275 foreach (var serviceInstance in instances) 276 { 277 Assert.True(typeof(ISampleService).IsAssignableFrom(serviceInstance?.GetType())); 278 Assert.NotNull(serviceInstance); 279 } 280 } 281 282 [Fact] 283 public void ContainerMustGracefullyHandleRecursiveServiceDependencies() 284 { 285 var container = new ServiceContainer(); 286 container.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "LinFu*.dll"); 287 288 container.AddService(typeof(SampleRecursiveTestComponent1), typeof(SampleRecursiveTestComponent1)); 289 container.AddService(typeof(SampleRecursiveTestComponent2), typeof(SampleRecursiveTestComponent2)); 290 291 try 292 { 293 var result = container.GetService<SampleRecursiveTestComponent1>(); 294 } 295 catch (Exception ex) 296 { 297 Assert.True(ex?.GetType() != typeof(StackOverflowException)); 298 } 299 } 300 301 [Fact] 302 public void ContainerMustHoldAnonymousFactoryInstance() 303 { 304 var mockFactory = new Mock<IFactory>(); 305 var container = new ServiceContainer(); 306 307 // Give it a random service interface type 308 var serviceType = typeof(IDisposable); 309 310 // Manually add the factory instance 311 container.AddFactory(serviceType, mockFactory.Object); 312 Assert.True(container.Contains(serviceType), 313 $"The container needs to have a factory for service type '{serviceType}'"); 314 } 315 316 [Fact] 317 public void ContainerMustHoldNamedFactoryInstance() 318 { 319 var mockFactory = new Mock<IFactory>(); 320 var container = new ServiceContainer(); 321 322 // Randomly assign an interface type 323 // NOTE: The actual interface type doesn't matter 324 var serviceType = typeof(ISerializable); 325 326 container.AddFactory("MyService", serviceType, mockFactory.Object); 327 Assert.True(container.Contains("MyService", serviceType), 328 "The container is supposed to contain a service named 'MyService'"); 329 330 var instance = new object(); 331 mockFactory.Expect(f => f.CreateInstance( 332 It.Is<IFactoryRequest>( 333 request => request.ServiceName == "MyService" && request.ServiceType == serviceType))) 334 .Returns(instance); 335 336 Assert.Same(instance, container.GetService("MyService", serviceType)); 337 } 338 339 [Fact] 340 public void ContainerMustInjectFactoryInstances() 341 { 342 var mockFactory = new Mock<IFactory<ISampleService>>(); 343 mockFactory.Expect(f => f.CreateInstance(It.IsAny<IFactoryRequest>())).Returns(new SampleClass()); 344 345 var container = new ServiceContainer(); 346 container.AddFactory(mockFactory.Object); 347 348 var instance = 349 (SampleClassWithFactoryDependency)container.AutoCreate(typeof(SampleClassWithFactoryDependency)); 350 351 Assert.NotNull(instance); 352 353 var factory = instance.Factory; 354 factory.CreateInstance(null); 355 356 mockFactory.VerifyAll(); 357 } 358 359 [Fact] 360 public void ContainerMustListAvailableNamedServices() 361 { 362 var container = new ServiceContainer(); 363 container.AddService<ISampleService>("MyService", new SampleClass()); 364 365 var availableServices = container.AvailableServices; 366 Assert.True(availableServices.Count() > 0); 367 368 // There should be a matching service type 369 // at this point 370 var matches = from s in availableServices 371 where 372 s.ServiceType == typeof(ISampleService) && 373 s.ServiceName == "MyService" 374 select s; 375 376 Assert.True(matches.Count() > 0); 377 } 378 379 [Fact] 380 public void ContainerMustListAvailableUnnamedServices() 381 { 382 var container = new ServiceContainer(); 383 container.AddService<ISampleService>(new SampleClass()); 384 385 var availableServices = container.AvailableServices; 386 Assert.True(availableServices.Count() > 0); 387 388 // There should be a matching service type 389 // at this point 390 var matches = from s in availableServices 391 where s.ServiceType == typeof(ISampleService) 392 select s; 393 394 Assert.True(matches.Count() > 0); 395 } 396 397 [Fact] 398 public void 399 ContainerMustLoadAnyGenericServiceTypeInstanceFromAGenericConcreteClassMarkedWithTheImplementsAttribute() 400 { 401 var container = new ServiceContainer(); 402 container.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "*.dll"); 403 404 var serviceName = "NonSpecificGenericService"; 405 406 // The container must be able to create any type that derives from ISampleService<T> 407 // despite whether or not the specific generic service type is explicitly registered as a service 408 Assert.True(container.Contains(serviceName, typeof(ISampleGenericService<int>))); 409 Assert.True(container.Contains(serviceName, typeof(ISampleGenericService<double>))); 410 Assert.True(container.Contains(serviceName, typeof(ISampleGenericService<string>))); 411 412 // Both service types must be valid services 413 Assert.NotNull(container.GetService<ISampleGenericService<int>>()); 414 Assert.NotNull(container.GetService<ISampleGenericService<double>>()); 415 Assert.NotNull(container.GetService<ISampleGenericService<string>>()); 416 } 417 418 [Fact] 419 public void ContainerMustLoadAssemblyFromMemory() 420 { 421 var container = new ServiceContainer(); 422 container.LoadFrom(typeof(SampleClass).Assembly); 423 424 // Verify that the container loaded the sample assembly into memory 425 Assert.True(container.Contains(typeof(ISampleService))); 426 } 427 428 [Fact] 429 public void 430 ContainerMustLoadSpecificGenericServiceTypesFromAGenericConcreteClassMarkedWithTheImplementsAttribute() 431 { 432 var container = new ServiceContainer(); 433 container.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "*.dll"); 434 435 var serviceName = "SpecificGenericService"; 436 437 // The container must be able to create both registered service types 438 Assert.True(container.Contains(serviceName, typeof(ISampleGenericService<int>))); 439 Assert.True(container.Contains(serviceName, typeof(ISampleGenericService<double>))); 440 441 // Both service types must be valid services 442 Assert.NotNull(container.GetService<ISampleGenericService<int>>()); 443 Assert.NotNull(container.GetService<ISampleGenericService<double>>()); 444 } 445 446 [Fact] 447 public void ContainerMustReturnServiceInstance() 448 { 449 var mockFactory = new Mock<IFactory>(); 450 var container = new ServiceContainer(); 451 452 var serviceType = typeof(ISerializable); 453 var instance = new object(); 454 455 container.AddFactory(serviceType, mockFactory.Object); 456 457 // The container must call the IFactory.CreateInstance method 458 mockFactory.Expect( 459 f => f.CreateInstance(It.Is<IFactoryRequest>(request => request.ServiceType == serviceType 460 && request.Container == container))).Returns( 461 instance); 462 463 var result = container.GetService(serviceType); 464 Assert.NotNull(result); 465 Assert.Same(instance, result); 466 467 mockFactory.VerifyAll(); 468 } 469 470 [Fact] 471 public void ContainerMustSupportGenericAddFactoryMethod() 472 { 473 var container = new ServiceContainer(); 474 var mockFactory = new Mock<IFactory<ISerializable>>(); 475 var mockService = new Mock<ISerializable>(); 476 477 container.AddFactory(mockFactory.Object); 478 mockFactory.Expect(f => f.CreateInstance(It.Is<IFactoryRequest>(request => request.Container == container))) 479 .Returns(mockService.Object); 480 481 Assert.NotNull(container.GetService<ISerializable>()); 482 } 483 484 [Fact] 485 public void ContainerMustSupportGenericGetServiceMethod() 486 { 487 var mockService = new Mock<ISerializable>(); 488 var mockFactory = new Mock<IFactory>(); 489 var container = new ServiceContainer(); 490 491 container.AddFactory(typeof(ISerializable), mockFactory.Object); 492 container.AddFactory("MyService", typeof(ISerializable), mockFactory.Object); 493 494 // Return the mock ISerializable instance 495 mockFactory.Expect(f => f.CreateInstance( 496 It.Is<IFactoryRequest>(request => request.Container == container && 497 request.ServiceType == typeof(ISerializable)))).Returns( 498 mockService.Object); 499 500 // Test the syntax 501 var result = container.GetService<ISerializable>(); 502 Assert.Same(mockService.Object, result); 503 504 result = container.GetService<ISerializable>("MyService"); 505 Assert.Same(mockService.Object, result); 506 } 507 508 509 [Fact] 510 public void ContainerMustSupportNamedGenericAddFactoryMethod() 511 { 512 var container = new ServiceContainer(); 513 var mockFactory = new Mock<IFactory<ISerializable>>(); 514 var mockService = new Mock<ISerializable>(); 515 516 container.AddFactory("MyService", mockFactory.Object); 517 mockFactory.Expect(f => f.CreateInstance(It.Is<IFactoryRequest>(request => request.Container == container))) 518 .Returns(mockService.Object); 519 520 Assert.NotNull(container.GetService<ISerializable>("MyService")); 521 } 522 523 [Fact] 524 public void ContainerMustThrowErrorIfServiceNotFound() 525 { 526 ExpectException<ServiceNotFoundException>(() => 527 { 528 var container = new ServiceContainer(); 529 var instance = container.GetService(typeof(ISerializable)); 530 Assert.Null(instance); 531 }); 532 } 533 534 [Fact] 535 public void ContainerMustUseUnnamedAddFactoryMethodIfNameIsNull() 536 { 537 var mockFactory = new Mock<IFactory>(); 538 var mockService = new Mock<ISerializable>(); 539 540 var container = new ServiceContainer(); 541 542 var serviceType = typeof(ISerializable); 543 544 // Add the service using a null name; 545 // the container should register this factory 546 // as if it had no name 547 container.AddFactory(null, serviceType, mockFactory.Object); 548 mockFactory.Expect(f => f.CreateInstance( 549 It.Is<IFactoryRequest>(request => request.Container == container && 550 request.ServiceType == serviceType))).Returns(mockService.Object); 551 552 // Verify the result 553 var result = container.GetService<ISerializable>(); 554 Assert.Same(mockService.Object, result); 555 } 556 557 [Fact] 558 public void ContainerMustUseUnnamedContainsMethodIfNameIsNull() 559 { 560 var mockFactory = new Mock<IFactory>(); 561 var mockService = new Mock<ISerializable>(); 562 var container = new ServiceContainer(); 563 564 var serviceType = typeof(ISerializable); 565 566 // Use unnamed AddFactory method 567 container.AddFactory(serviceType, mockFactory.Object); 568 569 // The container should use the 570 // IContainer.Contains(Type) method instead of the 571 // IContainer.Contains(string, Type) method if the 572 // service name is blank 573 Assert.True(container.Contains(null, typeof(ISerializable))); 574 } 575 576 [Fact] 577 public void ContainerMustUseUnnamedGetServiceMethodIfNameIsNull() 578 { 579 var mockFactory = new Mock<IFactory>(); 580 var mockService = new Mock<ISerializable>(); 581 var container = new ServiceContainer(); 582 583 584 var serviceType = typeof(ISerializable); 585 mockFactory.Expect( 586 f => f.CreateInstance(It.Is<IFactoryRequest>(request => request.ServiceType == serviceType))) 587 .Returns(mockService.Object); 588 container.AddFactory(serviceType, mockFactory.Object); 589 590 var result = container.GetService(null, serviceType); 591 592 Assert.Same(mockService.Object, result); 593 } 594 595// [Fact] 596// [Ignore("TODO: Implement this")] 597// public void ContainerServicesShouldBeLazyIfProxyFactoryExists() 598// { 599// var container = new ServiceContainer(); 600// container.AddService<IProxyFactory>(new ProxyFactory()); 601// Assert.True(container.Contains(typeof(IProxyFactory))); 602// 603// // The instance should never be created 604// container.AddService(typeof(ISampleService), typeof(SampleLazyService)); 605// 606// var result = container.GetService<ISampleService>(); 607// Assert.False(SampleLazyService.IsInitialized); 608 609// } 610 611 [Fact] 612 public void 613 ContainerShouldBeAbleToCreateAGenericServiceImplementationThatHasAConstructorWithPrimitiveArguments() 614 { 615 var container = new ServiceContainer(); 616 container.LoadFrom(typeof(SampleService<>).Assembly); 617 618 ISampleService<int> s = null; 619 // All fail with ServiceNotFoundException. 620 s = container.GetService<ISampleService<int>>(42, "frobozz", false); 621 Assert.NotNull(s); 622 623 s = container.GetService<ISampleService<int>>(42, "frobozz"); 624 Assert.NotNull(s); 625 s = container.GetService<ISampleService<int>>(42, false); 626 Assert.NotNull(s); 627 628 s = container.GetService<ISampleService<int>>(null, "frobozz", false); 629 Assert.NotNull(s); 630 } 631 632 [Fact] 633 public void ContainerShouldBeAbleToRegisterGenericTypeAndResolveConcreteServiceType() 634 { 635 var container = new ServiceContainer(); 636 container.AddService(typeof(ISampleGenericService<>), 637 typeof(SampleGenericClassWithOpenGenericImplementation<>)); 638 639 var instance = container.GetService<ISampleGenericService<int>>(); 640 Assert.NotNull(instance); 641 } 642 643 [Fact] 644 public void 645 ContainerShouldBeAbleToRegisterGenericTypeAndResolveConcreteServiceTypeUsingTheNonGenericGetServiceMethod() 646 { 647 var container = new ServiceContainer(); 648 container.AddService(typeof(ISampleGenericService<>), 649 typeof(SampleGenericClassWithOpenGenericImplementation<>)); 650 651 var instance = container.GetService(typeof(ISampleGenericService<int>)); 652 Assert.NotNull(instance); 653 } 654 655 [Fact] 656 public void ContainerShouldCallPreProcessor() 657 { 658 var mockPreprocessor = new Mock<IPreProcessor>(); 659 var mockService = new Mock<ISampleService>(); 660 661 mockPreprocessor.Expect(p => p.Preprocess(It.IsAny<IServiceRequest>())); 662 663 var container = new ServiceContainer(); 664 container.AddService("SomeService", mockService.Object); 665 container.PreProcessors.Add(mockPreprocessor.Object); 666 667 // The preprocessors should be called 668 var result = container.GetService<ISampleService>("SomeService"); 669 Assert.NotNull(result); 670 671 mockPreprocessor.VerifyAll(); 672 } 673 674 [Fact] 675 public void InitializerShouldOnlyBeCalledOncePerLifetime() 676 { 677 var container = new ServiceContainer(); 678 var mockService = new Mock<IInitialize>(); 679 680 VerifyInitializeCall(container, mockService); 681 VerifyInitializeCall(container, new Mock<IInitialize>()); 682 } 683 684 [Fact] 685 public void InterceptorClassesMarkedWithInterceptorAttributeMustGetActualTargetInstance() 686 { 687 var container = new ServiceContainer(); 688 container.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "*.dll"); 689 var mockService = new Mock<ISampleInterceptedInterface>(); 690 mockService.Expect(mock => mock.DoSomething()); 691 692 // Add the target instance 693 container.AddService(mockService.Object); 694 695 // The service must return a proxy 696 var service = container.GetService<ISampleInterceptedInterface>(); 697 Assert.NotSame(service, mockService.Object); 698 // Execute the method and 'catch' the target instance once the method call is made 699 service.DoSomething(); 700 701 var holder = container.GetService<ITargetHolder>("SampleInterceptorClass"); 702 Assert.Same(holder.Target, mockService.Object); 703 } 704 705 [Fact] 706 public void ShouldNotReturnNamedServicesForGetServiceCallsForAnonymousServices() 707 { 708 ExpectException<NamedServiceNotFoundException>(() => 709 { 710 var container = new ServiceContainer(); 711 var myService = new MyService(); 712 container.AddService<IMyService>(myService); 713 714 Assert.NotNull(container.GetService<IMyService>()); 715 716 Assert.Null(container.GetService<IMyService>("frobozz")); 717 }); 718 } 719 720 private void ExpectException<TException>(Action testToRun) 721 where TException : Exception 722 { 723 try 724 { 725 testToRun(); 726 } 727 catch (TException) 728 { 729 return; 730 } 731 732 Assert.False(true, $"Expected exception type '{typeof(TException).FullName}' not thrown"); 733 } 734 } 735}