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); }
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); }
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); }
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); }
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); } }
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()); }