public void Scopes_Factories()
        {
            IList <IServiceProvider> serviceProviders = new List <IServiceProvider>();

            var services = new ServiceCollection();

            services.AddTransient <A>(p =>
            {
                serviceProviders.Add(p);
                return(new A());
            });

            var rootScopeFactory = new WebHostServiceProvider(new ServiceCollection());
            var jobHostProvider  = new JobHostServiceProvider(services, rootScopeFactory, rootScopeFactory);

            // Get this service twice.
            // The IServiceProvider passed to the factory should be different because they are separate scopes.
            var scope1 = jobHostProvider.CreateScope();

            scope1.ServiceProvider.GetService <A>();

            var scope2 = jobHostProvider.CreateScope();

            scope2.ServiceProvider.GetService <A>();

            Assert.Equal(2, serviceProviders.Count);
            Assert.NotSame(serviceProviders[0], serviceProviders[1]);
        }
        public void Dispose_OnJobHostScope_DoesNotDisposeRootSingletonService()
        {
            var rootServices = new ServiceCollection();

            rootServices.AddSingleton <TestService>();
            var rootContainer = rootServices.BuildServiceProvider();

            // Get the root scope factory
            IServiceScopeFactory rootScopeFactory = rootContainer.GetRequiredService <IServiceScopeFactory>();

            var jobHostServices = new ServiceCollection();

            jobHostServices.AddScoped <IService, TestService>();
            IServiceProvider serviceProvider = new JobHostServiceProvider(jobHostServices, rootContainer, rootScopeFactory);

            // Create a scope on JobHost container
            IServiceScope scope = serviceProvider.CreateScope();

            // The service resolution should fallback to the parent scope
            TestService rootService = scope.ServiceProvider.GetService <TestService>();

            IService jobHostService = scope.ServiceProvider.GetService <IService>();

            scope.Dispose();

            // Disposing of the JobHost scope should not dispose of root container services
            Assert.False(rootService.Disposed);

            // Disposing of the JobHost scope should dispose of scoped JobHost services
            Assert.True(jobHostService.Disposed);
        }
예제 #3
0
        private static (IServiceProvider Default, IServiceProvider JobHost) SetupProviders(params ServiceLifetime[] lifetimes)
        {
            // Build ServiceProvider
            var defaultServices = new ServiceCollection();

            foreach (var lifetime in lifetimes)
            {
                defaultServices.Add(new ServiceDescriptor(typeof(UsingConstructor), typeof(UsingConstructor), lifetime));
                defaultServices.Add(new ServiceDescriptor(typeof(UsingFactory), p => new UsingFactory(p), lifetime));
            }
            IServiceProvider defaultProvider = defaultServices.BuildServiceProvider();

            // Build JobHostServiceProvider
            var rootServices  = new ServiceCollection();
            var rootContainer = rootServices.BuildServiceProvider();
            IServiceScopeFactory rootScopeFactory = rootContainer.GetRequiredService <IServiceScopeFactory>();
            var jobHostServices = new ServiceCollection();

            foreach (var lifetime in lifetimes)
            {
                jobHostServices.Add(new ServiceDescriptor(typeof(UsingConstructor), typeof(UsingConstructor), lifetime));
                jobHostServices.Add(new ServiceDescriptor(typeof(UsingFactory), p => new UsingFactory(p), lifetime));
            }
            IServiceProvider jobHostProvider = new JobHostServiceProvider(jobHostServices, rootContainer, rootScopeFactory);

            return(defaultProvider, jobHostProvider);
        }
예제 #4
0
        public void Scopes_Factories()
        {
            using (new TestScopedEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsFeatureFlags, ScriptConstants.FeatureFlagEnableEnhancedScopes))
            {
                IList <IServiceProvider> serviceProviders = new List <IServiceProvider>();

                var services = new ServiceCollection();
                services.AddTransient <A>(p =>
                {
                    serviceProviders.Add(p);
                    return(new A());
                });

                var rootScopeFactory = new WebHostServiceProvider(new ServiceCollection());
                var jobHostProvider  = new JobHostServiceProvider(services, rootScopeFactory, rootScopeFactory);

                // Get this service twice.
                // The IServiceProvider passed to the factory should be different because they are separate scopes.
                var scope1 = jobHostProvider.CreateScope();
                scope1.ServiceProvider.GetService <A>();

                var scope2 = jobHostProvider.CreateScope();
                scope2.ServiceProvider.GetService <A>();

                Assert.Equal(2, serviceProviders.Count);
                Assert.NotSame(serviceProviders[0], serviceProviders[1]);
            }
        }
        public void Scopes_ChildScopeIsIsolated()
        {
            var services = new ServiceCollection();

            services.AddScoped <A>();

            var rootScopeFactory = new WebHostServiceProvider(new ServiceCollection());
            var jobHostProvider  = new JobHostServiceProvider(services, rootScopeFactory, rootScopeFactory);

            var a1 = jobHostProvider.GetService <A>();

            jobHostProvider.CreateScope();
            var a2 = jobHostProvider.GetService <A>();

            Assert.NotNull(a1);
            Assert.NotNull(a2);
            Assert.Same(a1, a2);
        }
예제 #6
0
        public void Scopes_ChildScopeIsIsolated()
        {
            using (new TestScopedEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsFeatureFlags, ScriptConstants.FeatureFlagEnableEnhancedScopes))
            {
                var services = new ServiceCollection();
                services.AddScoped <A>();

                var rootScopeFactory = new WebHostServiceProvider(new ServiceCollection());
                var jobHostProvider  = new JobHostServiceProvider(services, rootScopeFactory, rootScopeFactory);

                var a1 = jobHostProvider.GetService <A>();
                jobHostProvider.CreateScope();
                var a2 = jobHostProvider.GetService <A>();
                Assert.NotNull(a1);
                Assert.NotNull(a2);
                Assert.Same(a1, a2);
            }
        }
        public void Dispose_OnJobHost_DoesNotDisposRootScopedService()
        {
            var rootServices = new ServiceCollection();

            rootServices.AddSingleton <TestService>();
            var rootContainer = rootServices.BuildServiceProvider();

            // Get the root scope factory
            IServiceScopeFactory rootScopeFactory = rootContainer.GetRequiredService <IServiceScopeFactory>();

            IServiceProvider serviceProvider = new JobHostServiceProvider(new ServiceCollection(), rootContainer, rootScopeFactory);

            // The service resolution should fallback to the parent scope
            TestService rootService = serviceProvider.GetService <TestService>();

            ((IDisposable)serviceProvider).Dispose();

            // Disposing of the JobHost service provider should not dispose of root container services
            Assert.False(rootService.Disposed);
        }
        public void Scopes_DelegateFactory()
        {
            var services = new ServiceCollection();

            services.AddScoped <A>();
            services.AddScoped <ServiceFactory>(provider => (type) => provider.GetRequiredService(type));

            var rootScopeFactory = new WebHostServiceProvider(new ServiceCollection());
            var jobHostProvider  = new JobHostServiceProvider(services, rootScopeFactory, rootScopeFactory);

            var scope1 = jobHostProvider.CreateScope();
            var a1     = scope1.ServiceProvider.GetService <ServiceFactory>()(typeof(A));

            var scope2 = jobHostProvider.CreateScope();
            var a2     = scope2.ServiceProvider.GetService <ServiceFactory>()(typeof(A));

            Assert.NotNull(a1);
            Assert.NotNull(a2);
            Assert.NotSame(a1, a2);
        }
        public void Dispose_OnJobHostScope_DisposesRootScopedService()
        {
            var rootServices = new ServiceCollection();

            rootServices.AddScoped <TestService>();
            var rootContainer = rootServices.BuildServiceProvider();

            // Get the root scope factory
            IServiceScopeFactory rootScopeFactory = rootContainer.GetRequiredService <IServiceScopeFactory>();

            IServiceProvider serviceProvider = new JobHostServiceProvider(new ServiceCollection(), rootContainer, rootScopeFactory);

            // Create a scope on JobHost container
            IServiceScope scope = serviceProvider.CreateScope();

            // The service resolution should fallback to the parent scope
            TestService rootService = scope.ServiceProvider.GetService <TestService>();

            scope.Dispose();

            // Disposing of the JobHost scope should also trigger a parent scope disposal
            Assert.True(rootService.Disposed);
        }
예제 #10
0
        public void Scopes_DelegateFactory(string flag)
        {
            using (new TestScopedEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsFeatureFlags, flag))
            {
                var services = new ServiceCollection();

                services.AddScoped <A>();
                services.AddScoped <ServiceFactory>(provider => (type) => provider.GetRequiredService(type));

                var rootScopeFactory = new WebHostServiceProvider(new ServiceCollection());
                var jobHostProvider  = new JobHostServiceProvider(services, rootScopeFactory, rootScopeFactory);

                var scope1 = jobHostProvider.CreateScope();
                var a1     = scope1.ServiceProvider.GetService <ServiceFactory>()(typeof(A));

                var scope2 = jobHostProvider.CreateScope();
                var a2     = scope2.ServiceProvider.GetService <ServiceFactory>()(typeof(A));

                Assert.NotNull(a1);
                Assert.NotNull(a2);
                Assert.NotSame(a1, a2);
            }
        }
예제 #11
0
        public void JobHostServiceProvider_SingletonAndScoped()
        {
            // Build JobHostServiceProvider
            var rootServices  = new ServiceCollection();
            var rootContainer = rootServices.BuildServiceProvider();
            IServiceScopeFactory rootScopeFactory = rootContainer.GetRequiredService <IServiceScopeFactory>();
            var jobHostServices = new ServiceCollection();

            jobHostServices.AddSingleton <SingletonConstructor>();
            jobHostServices.AddSingleton <SingletonFactory>(p => new SingletonFactory(p));

            jobHostServices.AddScoped <ScopedConstructor>();
            jobHostServices.AddScoped <ScopedFactory>(p => new ScopedFactory(p));

            IServiceProvider jobHostProvider = new JobHostServiceProvider(jobHostServices, rootContainer, rootScopeFactory);

            // Resolve some root services
            SingletonConstructor rootSingletonConstructor = jobHostProvider.GetService <SingletonConstructor>();
            SingletonFactory     rootSingletonFactory     = jobHostProvider.GetService <SingletonFactory>();
            ScopedConstructor    rootScopedConstructor    = jobHostProvider.GetService <ScopedConstructor>();
            ScopedFactory        rootScopedFactory        = jobHostProvider.GetService <ScopedFactory>();

            // Resolve some child scope services
            SingletonConstructor childSingletonConstructor1;
            SingletonFactory     childSingletonFactory1;
            ScopedConstructor    childScopedConstructor1;
            ScopedFactory        childScopedFactory1;

            using (var scope = jobHostProvider.CreateScope())
            {
                childSingletonConstructor1 = scope.ServiceProvider.GetService <SingletonConstructor>();
                childSingletonFactory1     = scope.ServiceProvider.GetService <SingletonFactory>();

                childScopedConstructor1 = scope.ServiceProvider.GetService <ScopedConstructor>();
                childScopedFactory1     = scope.ServiceProvider.GetService <ScopedFactory>();
            }

            // Do it again
            SingletonConstructor childSingletonConstructor2;
            SingletonFactory     childSingletonFactory2;
            ScopedConstructor    childScopedConstructor2;
            ScopedFactory        childScopedFactory2;

            using (var scope = jobHostProvider.CreateScope())
            {
                childSingletonConstructor2 = scope.ServiceProvider.GetService <SingletonConstructor>();
                childSingletonFactory2     = scope.ServiceProvider.GetService <SingletonFactory>();

                childScopedConstructor2 = scope.ServiceProvider.GetService <ScopedConstructor>();
                childScopedFactory2     = scope.ServiceProvider.GetService <ScopedFactory>();
            }

            // Ensure all ServiceProviders for Singletons are the same.
            Assert.Same(rootSingletonConstructor.ServiceProvider, childSingletonConstructor1.ServiceProvider);
            Assert.Same(childSingletonConstructor1.ServiceProvider, rootSingletonFactory.ServiceProvider);
            Assert.Same(rootSingletonFactory.ServiceProvider, childSingletonFactory1.ServiceProvider);

            // The root ServiceProviders for Scoped should also be the same.
            Assert.Same(childSingletonFactory1.ServiceProvider, rootScopedConstructor.ServiceProvider);
            Assert.Same(rootScopedConstructor.ServiceProvider, rootScopedFactory.ServiceProvider);

            // Root and child should not match for Scoped
            Assert.NotSame(rootScopedConstructor.ServiceProvider, childScopedConstructor1.ServiceProvider);
            Assert.NotSame(rootScopedFactory.ServiceProvider, childScopedFactory1.ServiceProvider);

            // Both Scopes should match
            Assert.Same(childScopedConstructor1.ServiceProvider, childScopedFactory1.ServiceProvider);
            Assert.Same(childScopedConstructor2.ServiceProvider, childScopedFactory2.ServiceProvider);

            // But not between scopes
            Assert.NotSame(childScopedConstructor1.ServiceProvider, childScopedConstructor2.ServiceProvider);
            Assert.NotSame(childScopedFactory1.ServiceProvider, childScopedFactory2.ServiceProvider);

            // Roots and Singletons are not disposed
            rootSingletonConstructor.DoSomething();
            rootSingletonFactory.DoSomething();
            rootScopedConstructor.DoSomething();
            rootScopedFactory.DoSomething();
            childSingletonConstructor1.DoSomething();
            childSingletonFactory1.DoSomething();
            childSingletonConstructor2.DoSomething();
            childSingletonFactory2.DoSomething();

            // Child scopes are disposed.
            Assert.Throws <ContainerException>(() => childScopedConstructor1.DoSomething());
            Assert.Throws <ContainerException>(() => childScopedFactory1.DoSomething());
            Assert.Throws <ContainerException>(() => childScopedConstructor2.DoSomething());
            Assert.Throws <ContainerException>(() => childScopedFactory2.DoSomething());
        }