public ConcurrentDictionary <int, IServiceProvider> Build()
        {
            var containerDictionary = new ConcurrentDictionary <int, IServiceProvider>();

            using (var scope = _masterServiceCollection.BuildServiceProvider().CreateScope())
            {
                foreach (var tenant in _tenants)
                {
                    //get registrations set for the specific tenant
                    var tenantScopedServiceDescriptors = _masterServiceCollection
                                                         .Where(x => x is TenantScopedServiceDescriptor scopedServiceDescriptor && scopedServiceDescriptor.Tenant.Id == tenant.Id)
                                                         .Select(x => (TenantScopedServiceDescriptor)x);

                    var tenantServiceCollection = new Microsoft.Extensions.DependencyInjection.ServiceCollection();
                    foreach (var tenantServiceDescriptor in tenantScopedServiceDescriptors)
                    {
                        tenantServiceCollection.Add(tenantServiceDescriptor);
                    }

                    //get registrations which are not tenant scoped
                    var generalScopeServiceDescriptors = _masterServiceCollection
                                                         .Where(x => x is ServiceDescriptor)
                                                         .ToList();
                    foreach (var serviceDescriptor in generalScopeServiceDescriptors)
                    {
                        if (serviceDescriptor is TenantScopedServiceDescriptor || serviceDescriptor is IServiceCollection || serviceDescriptor.ServiceType == typeof(ContainerBuilder))
                        {
                            continue;
                        }

                        try
                        {
                            var requiredService = scope.ServiceProvider.GetRequiredService(serviceDescriptor.ServiceType);
                            tenantServiceCollection.Add(new ServiceDescriptor(serviceDescriptor.ServiceType, requiredService));
                        }
                        catch
                        {
                            tenantServiceCollection.Add(serviceDescriptor);
                        }
                    }

                    containerDictionary.TryAdd(tenant.Id, tenantServiceCollection.BuildServiceProvider());
                }
            }

            return(containerDictionary);
        }
        public void ServiceDescriptors_AllowsRemovingPreviousRegisteredServices()
        {
            // Arrange
            var serviceCollection = new ServiceCollection();
            var descriptor1       = new ServiceDescriptor(typeof(IFakeService), new FakeService());
            var descriptor2       = new ServiceDescriptor(typeof(IFactoryService), typeof(TransientFactoryService), ServiceLifetime.Transient);

            // Act
            serviceCollection.Add(descriptor1);
            serviceCollection.Add(descriptor2);
            serviceCollection.Remove(descriptor1);

            // Assert
            var result = Assert.Single(serviceCollection);

            Assert.Same(result, descriptor2);
        }
Пример #3
0
        public void Replace_ReplacesFirstServiceWithMatchingServiceType()
        {
            // Arrange
            var collection  = new ServiceCollection();
            var descriptor1 = new ServiceDescriptor(typeof(IFakeService), typeof(FakeService), ServiceLifetime.Transient);
            var descriptor2 = new ServiceDescriptor(typeof(IFakeService), typeof(FakeService), ServiceLifetime.Transient);

            collection.Add(descriptor1);
            collection.Add(descriptor2);
            var descriptor3 = new ServiceDescriptor(typeof(IFakeService), typeof(FakeService), ServiceLifetime.Singleton);

            // Act
            collection.Replace(descriptor3);

            // Assert
            Assert.Equal(new[] { descriptor2, descriptor3 }, collection);
        }
Пример #4
0
        private void Setup(ServiceLifetime lifetime)
        {
            IServiceCollection services = new ServiceCollection();

            for (int i = 0; i < 10; i++)
            {
                services.Add(ServiceDescriptor.Describe(typeof(A), typeof(A), lifetime));
            }

            services.Add(ServiceDescriptor.Describe(typeof(B), typeof(B), lifetime));
            services.Add(ServiceDescriptor.Describe(typeof(C), typeof(C), lifetime));

            _serviceProvider = services.BuildServiceProvider(new ServiceProviderOptions()
            {
#if INTERNAL_DI
                Mode = ServiceProviderMode
#endif
            }).CreateScope().ServiceProvider;
        }
Пример #5
0
        /// <summary>
        /// Extension method for cloning an instace of <see cref="IServiceCollection"/>.
        /// </summary>
        /// <param name="serviceCollection"></param>
        /// <returns></returns>
        public static IServiceCollection Clone(this IServiceCollection serviceCollection)
        {
            IServiceCollection clone = new ServiceCollection();

            foreach (var service in serviceCollection)
            {
                clone.Add(service);
            }

            return(clone);
        }
        Clone(Microsoft.Extensions.DependencyInjection.IServiceCollection serviceCollection)
        {
            Microsoft.Extensions.DependencyInjection.IServiceCollection clone =
                new Microsoft.Extensions.DependencyInjection.ServiceCollection();
            foreach (Microsoft.Extensions.DependencyInjection.ServiceDescriptor service in serviceCollection)
            {
                clone.Add(service);
            }

            return(clone);
        }
        public void Add_AddsDescriptorToServiceDescriptors()
        {
            // Arrange
            var serviceCollection = new ServiceCollection();
            var descriptor        = new ServiceDescriptor(typeof(IFakeService), new FakeService());

            // Act
            serviceCollection.Add(descriptor);

            // Assert
            var result = Assert.Single(serviceCollection);

            Assert.Same(result, descriptor);
        }
Пример #8
0
        public void AddSequence_AddsServicesToCollection()
        {
            // Arrange
            var collection  = new ServiceCollection();
            var descriptor1 = new ServiceDescriptor(typeof(IFakeService), typeof(FakeService), ServiceLifetime.Transient);
            var descriptor2 = new ServiceDescriptor(typeof(IFakeOuterService), typeof(FakeOuterService), ServiceLifetime.Transient);
            var descriptors = new[] { descriptor1, descriptor2 };

            // Act
            var result = collection.Add(descriptors);

            // Assert
            Assert.Equal(descriptors, collection);
        }
        public static IServiceCollection ToDynamicProxyService(this IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            var serviceProvider      = services.BuildServiceProvider(false);
            var servicesDynamicProxy = new ServiceCollection();

            foreach (var service in services)
            {
                var implType = service.ImplementationType ?? service.ImplementationInstance?.GetType() ?? service.ImplementationFactory?.GetType().GetGenericArguments().FirstOrDefault();
                if (implType == null)
                {
                    continue;
                }

                var meta = FreeSql.DynamicProxy.GetAvailableMeta(implType);
                if (meta != null)
                {
                    var serviceType = service.ServiceType.GetTypeInfo();
                    if (serviceType.IsClass)
                    {
                        servicesDynamicProxy.Add(ServiceDescriptor.Describe(service.ServiceType, meta.ProxyType, service.Lifetime));
                        continue;
                    }
                    if (serviceType.IsGenericTypeDefinition)
                    {
                        servicesDynamicProxy.Add(ServiceDescriptor.Describe(meta.SourceType, meta.ProxyType, service.Lifetime));
                        continue;
                    }
                    if (service.ImplementationInstance != null)
                    {
                        var implementationInstance = service.ImplementationInstance;
                        servicesDynamicProxy.Add(ServiceDescriptor.Describe(meta.SourceType, sp => implementationInstance.ToDynamicProxy(), service.Lifetime));
                        continue;
                    }
                    if (service.ImplementationFactory != null)
                    {
                        var implementationFactory = service.ImplementationFactory;
                        servicesDynamicProxy.Add(ServiceDescriptor.Describe(meta.SourceType, sp => implementationFactory(sp).ToDynamicProxy(), service.Lifetime));
                        continue;
                    }
                    if (service.ImplementationType != null)
                    {
                        var implementationType = service.ImplementationType;
                        servicesDynamicProxy.Add(ServiceDescriptor.Describe(meta.SourceType, sp => sp.GetService(implementationType).ToDynamicProxy(), service.Lifetime));
                        continue;
                    }
                }
                servicesDynamicProxy.Add(service);
            }

            serviceProvider.Dispose();
            return(servicesDynamicProxy);
        }
Пример #10
0
        public void Replace_AddsServiceIfServiceTypeIsNotRegistered()
        {
            // Arrange
            var collection  = new ServiceCollection();
            var descriptor1 = new ServiceDescriptor(typeof(IFakeService), typeof(FakeService), ServiceLifetime.Transient);
            var descriptor2 = new ServiceDescriptor(typeof(IFakeOuterService), typeof(FakeOuterService), ServiceLifetime.Transient);

            collection.Add(descriptor1);

            // Act
            collection.Replace(descriptor2);

            // Assert
            Assert.Equal(new[] { descriptor1, descriptor2 }, collection);
        }
Пример #11
0
        public void TestMakeReadOnly()
        {
            var serviceCollection = new ServiceCollection();
            var descriptor        = new ServiceDescriptor(typeof(IFakeService), new FakeService());

            serviceCollection.Add(descriptor);

            serviceCollection.MakeReadOnly();

            var descriptor2 = new ServiceDescriptor(typeof(IFakeEveryService), new FakeService());

            Assert.Throws <InvalidOperationException>(() => serviceCollection[0] = descriptor2);
            Assert.Throws <InvalidOperationException>(() => serviceCollection.Clear());
            Assert.Throws <InvalidOperationException>(() => serviceCollection.Remove(descriptor));
            Assert.Throws <InvalidOperationException>(() => serviceCollection.Add(descriptor2));
            Assert.Throws <InvalidOperationException>(() => serviceCollection.Insert(0, descriptor2));
            Assert.Throws <InvalidOperationException>(() => serviceCollection.RemoveAt(0));

            Assert.True(serviceCollection.IsReadOnly);
            Assert.Equal(1, serviceCollection.Count);
            foreach (ServiceDescriptor d in serviceCollection)
            {
                Assert.Equal(descriptor, d);
            }
            Assert.Equal(descriptor, serviceCollection[0]);
            Assert.True(serviceCollection.Contains(descriptor));
            Assert.Equal(0, serviceCollection.IndexOf(descriptor));

            ServiceDescriptor[] copyArray = new ServiceDescriptor[1];
            serviceCollection.CopyTo(copyArray, 0);
            Assert.Equal(descriptor, copyArray[0]);

            // ensure MakeReadOnly can be called twice, and it is just ignored
            serviceCollection.MakeReadOnly();
            Assert.True(serviceCollection.IsReadOnly);
        }
Пример #12
0
        public void TryAdd_WithType_DoesNotAddDuplicate(
            Action <IServiceCollection> addAction,
            Type expectedServiceType,
            Type expectedImplementationType,
            ServiceLifetime expectedLifetime)
        {
            // Arrange
            var collection = new ServiceCollection();

            collection.Add(ServiceDescriptor.Transient(expectedServiceType, expectedServiceType));

            // Act
            addAction(collection);

            // Assert
            var descriptor = Assert.Single(collection);

            Assert.Equal(expectedServiceType, descriptor.ServiceType);
            Assert.Same(expectedServiceType, descriptor.ImplementationType);
            Assert.Equal(ServiceLifetime.Transient, descriptor.Lifetime);
        }
        public static void FirstRegister <TService, TImplementation>(this IServiceCollection services, RegisterService <TService, TImplementation> registerService)
            where TService : class
            where TImplementation : class, TService
        {
            IServiceCollection newServicesCollection = new ServiceCollection();
            int first = -1;

            for (int i = 0; i < services.Count; i++)
            {
                if (services[i].ServiceType == typeof(TService))
                {
                    first = i;
                    break;
                }
            }

            if (first == -1)
            {
                registerService(services);
            }
            else
            {
                foreach (var item in services)
                {
                    if (first-- == 0)
                    {
                        registerService(newServicesCollection);
                    }
                    newServicesCollection.Add(item);
                }

                services.Clear();

                foreach (var service in newServicesCollection)
                {
                    services.Add(service);
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Builds interceptable <see cref="IServiceProvider"/>.
        /// </summary>
        /// <param name="services">The contract for a collection of service descriptors.</param>
        /// <param name="configure">The <see cref="Action{InterceptionBuilder}"/> used to perform more service registrations.</param>
        /// <returns>The current <see cref="IServiceCollection"/>.</returns>
        public static IServiceProvider BuildInterceptableServiceProvider(
            this IServiceCollection services,
            Action <InterceptionBuilder> configure = null)
        {
            Guard.ArgumentNotNull(services, nameof(services));
            services.TryAddInterception(configure);
            var provider             = services.BuildServiceProvider();
            var factoryCache         = provider.GetRequiredService <IInterceptableProxyFactoryCache>();
            var resolver             = provider.GetRequiredService <IInterceptorResolver>();
            var codeGeneratorFactory = provider.GetRequiredService <ICodeGeneratorFactory>();

            IServiceCollection newServices = new ServiceCollection();

            foreach (var service in services)
            {
                foreach (var newService in new ServiceDescriptorConverter(service, resolver, factoryCache, codeGeneratorFactory).AsServiceDescriptors())
                {
                    newServices.Add(newService);
                }
            }
            return(newServices.BuildServiceProvider());
        }
Пример #15
0
 /// <summary>
 /// Builds a service provider from supplied collections.
 /// </summary>
 /// <param name="sc"></param>
 /// <param name="serviceCollection"></param>
 /// <returns></returns>
 public static IServiceProvider BuildServiceProvider(this IServiceCollection sc, ServiceCollection serviceCollection)
 {
     sc.ToList().ForEach(sd => serviceCollection.Add(sd));
     return(serviceCollection.BuildServiceProvider());
 }