public void GetService_caches_the_result_from_the_underlying_resolver_for_a_given_type_name_pair()
            {
                var mockResolver    = new Mock <IDbDependencyResolver>();
                var cachingResolver = new CachingDependencyResolver(mockResolver.Object);

                VerifyServiceIsCached(new Mock <IPilkington>().Object, cachingResolver, mockResolver, "Foo");
                VerifyServiceIsCached(new Mock <IPilkington>().Object, cachingResolver, mockResolver, "Bar");
                VerifyServiceIsCached(new Mock <IPilkington>().Object, cachingResolver, mockResolver, null);

                VerifyServiceIsCached(new Mock <IGervais>().Object, cachingResolver, mockResolver, "Foo");
                VerifyServiceIsCached(new Mock <IGervais>().Object, cachingResolver, mockResolver, "Bar");
                VerifyServiceIsCached(new Mock <IGervais>().Object, cachingResolver, mockResolver, null);
            }
            private static void VerifyServiceIsCached <T>(
                T service,
                CachingDependencyResolver cachingResolver,
                Mock <IDbDependencyResolver> mockResolver,
                string name)
            {
                mockResolver.Setup(m => m.GetService(typeof(T), name)).Returns(service);

                Assert.Same(service, cachingResolver.GetService <T>(name));
                mockResolver.Verify(m => m.GetService(typeof(T), name), Times.Once());
                Assert.Same(service, cachingResolver.GetService <T>(name));
                mockResolver.Verify(m => m.GetService(typeof(T), name), Times.Once()); // Underlying resolver not called again
            }
            public void A_service_that_resolves_to_null_is_still_cached()
            {
                var mockResolver = new Mock <IDbDependencyResolver>();

                mockResolver.Setup(m => m.GetServices(typeof(IPilkington), null)).Returns(Enumerable.Empty <object>());

                var cachingResolver = new CachingDependencyResolver(mockResolver.Object);

                Assert.Empty(cachingResolver.GetServices <IPilkington>());
                mockResolver.Verify(m => m.GetServices(typeof(IPilkington), null), Times.Once());
                Assert.Empty(cachingResolver.GetServices <IPilkington>());
                mockResolver.Verify(m => m.GetServices(typeof(IPilkington), null), Times.Once()); // Underlying resolver not called again
            }
            public void GetService_can_be_accessed_from_multiple_threads_concurrently()
            {
                for (var i = 0; i < 30; i++)
                {
                    var bag      = new ConcurrentBag <IPilkington>();
                    var karl     = new Mock <IPilkington>().Object;
                    var resolver = new CachingDependencyResolver(new SingletonDependencyResolver <IPilkington>(karl));

                    ExecuteInParallel(() => bag.Add(resolver.GetService <IPilkington>()));

                    Assert.Equal(20, bag.Count);
                    Assert.True(bag.All(c => karl == c));
                }
            }