/// <summary> /// 使用工厂方法向应用程序添加和配置IMultiTenantStrategy。 /// </summary> /// <typeparam name="TStrategy">策略类 类型</typeparam> /// <param name="lifetime">生命周期</param> /// <param name="factory">工厂</param> /// <returns>返回当前类实例</returns> public MultiTenantBuilder WithStrategy <TStrategy>(ServiceLifetime lifetime, Func <IServiceProvider, TStrategy> factory) where TStrategy : IMultiTenantStrategy { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } Services.Add(ServiceDescriptor.Describe(typeof(IMultiTenantStrategy), sp => new MultiTenantStrategyWrapper <TStrategy>(factory(sp), sp.GetService <ILogger <TStrategy> >()), lifetime)); return(this); }
/// <summary> /// Adds AWS ECS container metadata service to the collection. /// </summary> /// <param name="collection">Service collection.</param> /// <param name="lifetime">Service lifetime.</param> /// <returns>A reference to the current instance of <see cref="IServiceCollection"/>.</returns> public static IServiceCollection AddAWSContainerMetadataService(this IServiceCollection collection, ServiceLifetime lifetime = ServiceLifetime.Singleton) { if (collection == null) { throw new ArgumentNullException(nameof(collection)); } return(collection.Add(new List <ServiceDescriptor> { ServiceDescriptor.Describe(typeof(IAWSContainerMetadata), typeof(AWSContainerMetadata), lifetime), ServiceDescriptor.Describe(typeof(IAWSContainerMetadataClient), typeof(AWSContainerMetadataHttpClient), lifetime), })); }
public IDependencyConfigurator Add( Type serviceType, Type implementationType, InstanceLifetime lifetime) { this.services.Add( ServiceDescriptor.Describe( serviceType, implementationType, ParseLifetime(lifetime))); return(this); }
private void RegisterAspectConfiguration(AspectConfiguration aspectConfiguration) { if (aspectConfiguration.ServiceDescriptor.ImplementationType != null) { Services.TryAdd(ServiceDescriptor.Describe(aspectConfiguration.ServiceDescriptor.ImplementationType, aspectConfiguration.ServiceDescriptor.ImplementationType, aspectConfiguration.ServiceDescriptor.Lifetime)); } Services.Add(ServiceDescriptor.Describe(aspectConfiguration.ServiceDescriptor.ServiceType, serviceProvider => InvokeCreateFactory(serviceProvider, aspectConfiguration), aspectConfiguration.ServiceDescriptor.Lifetime)); }
public IDependencyConfigurator Add <TImplementation>( Type serviceType, Func <IDependencyResolver, TImplementation> factory, InstanceLifetime lifetime) { this.services.Add( ServiceDescriptor.Describe( serviceType, provider => factory(new MicrosoftDependencyResolver(provider)), ParseLifetime(lifetime))); return(this); }
/// <summary> /// Adds 'tenant database support'. /// </summary> /// <param name="builder">Options builder.</param> /// <param name="addTenantSupport">Indication whether to enable or disable the feature.</param> /// <param name="databaseProviderLifetime">The lifetime of the provided <typeparamref name="TTenantDatabaseProviderFactory"/>.</param> /// <returns>Provided <paramref name="builder"/>.</returns> public static SqlServerDbContextOptionsBuilder AddTenantDatabaseSupport <TTenantDatabaseProviderFactory>( this SqlServerDbContextOptionsBuilder builder, bool addTenantSupport = true, ServiceLifetime databaseProviderLifetime = ServiceLifetime.Singleton) where TTenantDatabaseProviderFactory : ITenantDatabaseProviderFactory { builder.AddOrUpdateExtension(extension => { extension.AddTenantDatabaseSupport = addTenantSupport; extension.Add(ServiceDescriptor.Describe(typeof(ITenantDatabaseProviderFactory), typeof(TTenantDatabaseProviderFactory), databaseProviderLifetime)); }); return(builder); }
/// <inheritdoc /> protected override void ConfigureServices(IServiceCollection services) { base.ConfigureServices(services); services.AddAppCore() .AddModelValidation(); services.TryAddEnumerable( ServiceDescriptor.Describe( typeof(ICommandPipelineBehavior <,>), typeof(CommandValidationBehavior <,>), ((CommandModelFacility)Facility).Lifetime)); }
private static ServiceDescriptor describeReplacement <TInterface>( ServiceDescriptor component, ObjectFactory decorationFactory ) where TInterface : class { var decoratedComponent = decorateComponent <TInterface>(component, decorationFactory); return(ServiceDescriptor.Describe( typeof(TInterface), decoratedComponent, component.Lifetime)); }
public ClientPeerStateBuilder AddStateListener <T>() where T : IPeerStateHandler { ClientStateBuilder.ClientBuilder.Configure(s => { s.TryAddEnumerable( ServiceDescriptor.Describe( typeof(IPeerStateHandler), typeof(T), ServiceLifetime.Singleton)); }); return(this); }
private static IActiveMqBuilder AddProducer <TProducer>(this IActiveMqBuilder builder, ProducerConfiguration producerConfiguration, ServiceLifetime producerLifetime) where TProducer : class { if (builder.Services.Any(x => x.ServiceType == typeof(TProducer))) { var message = $"There has already been registered Producer with the type '{typeof(TProducer).FullName}'. " + "Typed Producer must be unique. " + "Consider using inheritance to create multiple unique types with the same API surface."; throw new InvalidOperationException(message); } builder.Services.Configure <ActiveMqOptions>(builder.Name, options => { if (!options.AddressConfigurations.TryGetValue(producerConfiguration.Address, out var routingTypes)) { routingTypes = new HashSet <RoutingType>(); options.AddressConfigurations.Add(producerConfiguration.Address, routingTypes); } if (producerConfiguration.RoutingType.HasValue) { routingTypes.Add(producerConfiguration.RoutingType.Value); } else { routingTypes.Add(RoutingType.Anycast); routingTypes.Add(RoutingType.Multicast); } }); builder.Services.AddSingleton(provider => { var sendObservable = provider.GetServices <SendObservable>().Single(x => x.Name == builder.Name); var logger = provider.GetService <ILogger <TypedActiveMqProducer <TProducer> > >(); var contextualSendObservable = new ContextualSendObservable(sendObservable) { Address = producerConfiguration.Address, RoutingType = producerConfiguration.RoutingType }; return(new TypedActiveMqProducer <TProducer>(logger, async token => { var connection = await provider.GetConnection(builder.Name, token); return await connection.CreateProducerAsync(producerConfiguration, token).ConfigureAwait(false); }, contextualSendObservable)); }); builder.Services.AddSingleton <IActiveMqProducer>(provider => provider.GetRequiredService <TypedActiveMqProducer <TProducer> >()); builder.Services.Add(ServiceDescriptor.Describe(typeof(TProducer), provider => ActivatorUtilities.CreateInstance <TProducer>(provider, provider.GetRequiredService <TypedActiveMqProducer <TProducer> >()), producerLifetime)); return(builder); }
/// <summary> /// Adds casbin core services to the specified <see cref="IServiceCollection" /> /// </summary> /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param> /// <param name="configureOptions"></param> /// <param name="defaultEnforcerProviderLifeTime">The lifetime with which to register the IEnforcerProvider service in the container.</param> /// <param name="defaultModelProviderLifeTime">The lifetime with which to register the ICasbinModelProvider service in the container.</param> /// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns> public static IServiceCollection AddCasbin(this IServiceCollection services, Action <CasbinAuthorizationOptions>?configureOptions = default, ServiceLifetime defaultEnforcerProviderLifeTime = ServiceLifetime.Scoped, ServiceLifetime defaultModelProviderLifeTime = ServiceLifetime.Scoped) { services.Configure(configureOptions); services.TryAdd(ServiceDescriptor.Describe( typeof(ICasbinModelProvider), typeof(DefaultCasbinModelProvider), defaultModelProviderLifeTime)); services.TryAdd(ServiceDescriptor.Describe( typeof(IEnforcerProvider), typeof(DefaultEnforcerProvider), defaultEnforcerProviderLifeTime)); return(services); }
public ServiceDescriptor Convert(ServiceDescriptor descriptor) { var type = creator.CreateProxyType(descriptor.ServiceType, ProxyTypes.Facade); return(ServiceDescriptor.Describe(descriptor.ServiceType, i => { var proxy = ActivatorUtilities.CreateInstance(i, type); var f = proxy.GetType().GetField("instance", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); f.SetValue(proxy, descriptor.ImplementationFactory != null ? descriptor.ImplementationFactory(i) : (descriptor.ImplementationInstance != null ? descriptor.ImplementationInstance : ActivatorUtilities.CreateInstance(i, descriptor.ImplementationType))); return proxy; }, descriptor.Lifetime)); }
private static void AddProxy <TService, TImplementation>(IServiceCollection services, ServiceLifetime serviceLifetime) { var descriptor = ServiceDescriptor.Describe( typeof(TService), sp => { return(ProxyDispatcher <TService> .Resolve( (TService)ActivatorUtilities.GetServiceOrCreateInstance(sp, typeof(TImplementation)) )); }, serviceLifetime); services.Add(descriptor); }
/// <summary> /// Register the tenant resolver implementation. /// </summary> /// <typeparam name="V"></typeparam> /// <param name="lifetime"></param> /// <returns></returns> public TenantBuilder <T> WithResolutionStrategy <V>(ServiceLifetime lifetime = ServiceLifetime.Transient) where V : class, ITenantResolver { _services.AddSingleton <RouteTranslator>(); _services.AddTransient <TenantAccessService <T> >(); _services.AddTransient(typeof(ITenantAccessor <T>), typeof(TenantAccessor <T>)); _services.AddTransient <ICurrentUserService, CurrentUserService>(); _services.AddTransient <IApplicationVersion, ApplicationVersion>(); _services.AddHttpContextAccessor(); _services.AddHostedService <PublishService>(); _services.Add(ServiceDescriptor.Describe(typeof(ITenantResolver), typeof(V), lifetime)); return(this); }
public void ManyConstructorTest() { List <ServiceDescriptor> serviceDescriptors = new List <ServiceDescriptor>(); serviceDescriptors.Add(ServiceDescriptor.Describe(typeof(ManyCtor), typeof(ManyCtor), ServiceLifetime.Transient)); serviceDescriptors.Add(ServiceDescriptor.Describe(typeof(ManyCtor2), typeof(ManyCtor2), ServiceLifetime.Transient)); serviceDescriptors.Add(ServiceDescriptor.Describe(typeof(Foo), typeof(Foo), ServiceLifetime.Singleton)); serviceDescriptors.Add(ServiceDescriptor.Describe(typeof(Boo), typeof(Boo), ServiceLifetime.Transient)); ServiceProvider service = new ServiceProvider(serviceDescriptors); Assert.IsNotNull(service.GetService(typeof(ManyCtor))); Assert.ThrowsException <InvalidOperationException>(() => service.GetService(typeof(ManyCtor2))); }
public static IMvcBuilder AddControllersAsServices(this IMvcBuilder builder, ServiceLifetime lifetime) { var feature = new ControllerFeature(); builder.PartManager.PopulateFeature(feature); foreach (var controller in feature.Controllers.Select(c => c.AsType())) { builder.Services.Add(ServiceDescriptor.Describe(controller, controller, lifetime)); } builder.Services.Replace(ServiceDescriptor.Transient <IControllerActivator, ServiceBasedControllerActivator>()); return(builder); }
/// <inheritdoc /> protected override void ConfigureServices(IServiceCollection services) { base.ConfigureServices(services); services.TryAddEnumerable( new[] { ServiceDescriptor.Singleton <ICommandPrincipalProvider, CommandPrincipalProvider>(), ServiceDescriptor.Singleton <ICommandMetadataProvider, AuthorizedCommandMetadataProvider>(), ServiceDescriptor.Describe( typeof(ICommandPipelineBehavior <,>), typeof(AuthenticatedCommandBehavior <,>), ((CommandModelFacility)Facility).Lifetime) }); }
public static void AddJLocalizer(this IServiceCollection services, Action <JLocalizerResourceService> localizerResource, ServiceLifetime serviceLifetime) { services.Replace(ServiceDescriptor.Describe(typeof(IStringLocalizerFactory), typeof(JStringLocalizerFactory), serviceLifetime)); services.Add(ServiceDescriptor.Describe(typeof(IStringLocalizer <>), typeof(JStringLocalizer <>), serviceLifetime)); ServiceDescriptor.Describe(typeof(IStringLocalizer), x => { var options = x.GetService <IOptions <JLocalizationOptions> >(); var factory = x.GetService <IStringLocalizerFactory>(); return(factory.Create(options.Value.Resources.ElementAtOrDefault(0).Key)); }, serviceLifetime); services.AddSingleton <IExternalLocalizerFactory, ExternalLocalizerFactory>(); localizerResource(new JLocalizerResourceService(services)); }
public void EnumerableTest() { List <ServiceDescriptor> serviceDescriptors = new List <ServiceDescriptor>(); serviceDescriptors.Add(ServiceDescriptor.Describe(typeof(Foo), typeof(Foo), ServiceLifetime.Singleton)); serviceDescriptors.Add(ServiceDescriptor.Describe(typeof(Foo), typeof(Foo), ServiceLifetime.Transient)); serviceDescriptors.Add(ServiceDescriptor.Describe(typeof(Foo), new Foo())); serviceDescriptors.Add(ServiceDescriptor.Describe(typeof(Foo), new Foo())); ServiceProvider service = new ServiceProvider(serviceDescriptors); IEnumerable <Foo> foos = service.GetService(typeof(IEnumerable <Foo>)) as IEnumerable <Foo>; Assert.AreEqual(foos.Count(), 4); }
private static IServiceCollection Replace <TService, TImplementation>(IServiceCollection services, ServiceLifetime lifetime) { for (var i = 0; i < services.Count; i++) { if (services[i].ServiceType == typeof(TService)) { services[i] = new ServiceDescriptor(typeof(TService), typeof(TImplementation), lifetime); return(services); } } services.Add(ServiceDescriptor.Describe(typeof(TService), typeof(TImplementation), lifetime)); return(services); }
private static IServiceCollection Replace <TService>(IServiceCollection services, Func <IServiceProvider, object> factory, ServiceLifetime lifetime) { for (var i = 0; i < services.Count; i++) { if (services[i].ServiceType == typeof(TService)) { services[i] = new ServiceDescriptor(typeof(TService), factory, lifetime); return(services); } } services.Add(ServiceDescriptor.Describe(typeof(TService), factory, lifetime)); return(services); }
private static ServiceDescriptor Decorate(ServiceDescriptor serviceDescriptor) { object DecoratedFactory(IServiceProvider serviceProvider) { var implementation = serviceProvider.GetInstance(serviceDescriptor); var decorator = serviceProvider.GetRequiredService <Decorator>(); return(decorator.For(serviceDescriptor.ServiceType, implementation)); } return(ServiceDescriptor.Describe( serviceType: serviceDescriptor.ServiceType, implementationFactory: DecoratedFactory, lifetime: serviceDescriptor.Lifetime)); }
public static IServiceCollection DecorateWithDispatchProxy <TInterface, TProxy>(this IServiceCollection services) where TInterface : class where TProxy : DispatchProxy { MethodInfo createMethod; try { createMethod = typeof(TProxy) .GetMethods(BindingFlags.Public | BindingFlags.Static) .First(info => !info.IsGenericMethod && info.ReturnType == typeof(TInterface)); } catch (Exception e) { throw new Exception("An error has occured while finding create method in given interface"); } var argInfos = createMethod.GetParameters(); var descriptorsToDecorate = services.Where(s => s.ServiceType == typeof(TInterface)).ToList(); if (descriptorsToDecorate.Count == 0) { throw new InvalidOperationException("There are no services are present in ServiceCollection"); } foreach (var descriptor in descriptorsToDecorate) { var decorated = ServiceDescriptor.Describe(typeof(TInterface), sp => { var decoratorInstance = createMethod.Invoke(null, argInfos.Select( info => info.ParameterType == (descriptor.ServiceType ?? descriptor.ImplementationType) ? sp.CreateInstance(descriptor) : sp.GetRequiredService(info.ParameterType)) .ToArray()); return((TInterface)decoratorInstance); }, descriptor.Lifetime); services.Remove(descriptor); services.Add(decorated); } return(services); }
public void ApplyServices(IServiceCollection services) #endif { services.AddSingleton(_migrationOptions); var oldCustomizer = services.First(p => p.ServiceType == typeof(IModelCustomizer)); services.Remove(oldCustomizer); services.Add(ServiceDescriptor.Describe(oldCustomizer.ImplementationType, oldCustomizer.ImplementationType, oldCustomizer.Lifetime)); var newCustomizer = typeof(DataMigrationModelCustomizer <>).MakeGenericType(oldCustomizer.ImplementationType); services.Add(ServiceDescriptor.Describe(typeof(IModelCustomizer), newCustomizer, oldCustomizer.Lifetime)); #if EF2_2 return(true); #endif }
public void Transfer(IServiceCollection services) { foreach (var registration in _registrations) { if (registration.Instance != null) { var descriptor = ServiceDescriptor.Describe(registration.ServiceType, f => registration.Instance, registration.Lifetime); services.Add(descriptor); } else { var descriptor = ServiceDescriptor.Describe(registration.ServiceType, registration.ImplementationType, registration.Lifetime); services.Add(descriptor); } } }
public async Task ValidateAsync_WithValidatorOfTAndTContextFromDependencyInjection_InvokesHandlersAndReturnsExpectedResult() { // Arrange var items = new[] { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; var rules = new IValidationRule <int, string>[] { new GreaterThanRule <string>(5), new GreaterThanRule <string>(7), new LowerThanRule <string>(10), new LowerThanRule <string>(12) }; var services = new ServiceCollection(); services .AddValidator <int, string>() .AddScoped(p => rules[0]) .AddScoped(p => rules[1]) .AddScoped(p => rules[2]) .AddScoped(p => rules[3]) .AddSingleton <IValidationRuleHandler <int, string> >(p => new ContextualizedTestHandler <int, string>()) .Add(ServiceDescriptor.Describe(typeof(IValidationRuleHandler <,>), typeof(ContextualizedTestHandler <,>), ServiceLifetime.Singleton)); var provider = services.BuildServiceProvider(); var scope = provider.CreateScope(); var handlers = scope.ServiceProvider.GetServices <IValidationRuleHandler <int, string> >(); // Act var validator = scope.ServiceProvider.GetService <IValidator <int, string> >(); var results = await validator.ValidateAsync(items, "test"); // Assert Assert.Equal(2, handlers.Count()); Assert.All(handlers, h => Assert.Equal(4, ((ContextualizedTestHandler <int, string>)h).HandleCount)); Assert.Equal(10, results.Count()); Assert.Equal(new[] { "NOT_GREATER_THAN_5", "NOT_GREATER_THAN_7" }, results[4].ErrorCodes()); Assert.Equal(new[] { "NOT_GREATER_THAN_5", "NOT_GREATER_THAN_7" }, results[5].ErrorCodes()); Assert.Equal(new[] { "NOT_GREATER_THAN_7" }, results[6].ErrorCodes()); Assert.Equal(new[] { "NOT_GREATER_THAN_7" }, results[7].ErrorCodes()); Assert.True(results[8].Valid()); Assert.True(results[9].Valid()); Assert.Equal(new[] { "NOT_LOWER_THAN_10" }, results[10].ErrorCodes()); Assert.Equal(new[] { "NOT_LOWER_THAN_10" }, results[11].ErrorCodes()); Assert.Equal(new[] { "NOT_LOWER_THAN_10", "NOT_LOWER_THAN_12" }, results[12].ErrorCodes()); Assert.Equal(new[] { "NOT_LOWER_THAN_10", "NOT_LOWER_THAN_12" }, results[13].ErrorCodes()); }
/// <summary> /// This method decorates handlers or decorators /// </summary> /// <param name="services">Service container for the Dependency Injection</param> /// <param name="interfaceType">Type of the ICommandHandler interface including the generic type</param> /// <param name="genericDecoratorType">Decorator type to use for the current decoration</param> /// <param name="requiredAttributeType">Optional attribute that if provided must be present in the command or query in order to enable the current decoration</param> /// <param name="optionalDependencyType">Optional interface type that if provided will be used to create an instance passed as parameter to the current decorator</param> private static void DecorateHandlerdescriptors(IServiceCollection services, Type interfaceType, Type genericDecoratorType, Type requiredAttributeType = null, Type optionalDependencyType = null) { if (requiredAttributeType != null) { // Target type could be ICommand or IQuery var targetType = interfaceType.GetGenericArguments().FirstOrDefault(); if (targetType == null) { return; } var attribute = TypeDescriptor.GetAttributes(targetType)[requiredAttributeType]; // If the required attribute is not present, do not register the current decorator if (attribute == null) { return; } } foreach (var descriptor in services.GetDescriptors(interfaceType)) { object Factory(IServiceProvider serviceProvider) { // Get the instance of the previous decorator var handler = descriptor.ImplementationType != null // Used when decorating the handler the first time ? serviceProvider.GetService(descriptor.ImplementationType) // Used when decorating another decorator : descriptor.ImplementationFactory(serviceProvider); // Create the decorator type including generic types var decoratorType = genericDecoratorType.MakeGenericType(interfaceType.GetGenericArguments()); // Create the logger type var loggerType = typeof(ILogger <>).MakeGenericType(decoratorType); return(optionalDependencyType == null // Standard decorator and handler constructor ? Activator.CreateInstance(decoratorType, handler, serviceProvider.GetService(loggerType)) // Custom decorator constructor that receives an additional type : Activator.CreateInstance(decoratorType, handler, serviceProvider.GetService(loggerType), serviceProvider.GetService(optionalDependencyType))); } services.Replace(ServiceDescriptor.Describe(descriptor.ServiceType, Factory, ServiceLifetime.Transient)); } }
/// <summary> /// /// </summary> /// <param name="item"></param> /// <returns></returns> public static ServiceDescriptor CreateServiceDescriptor(this ServiceDescriptorConfiguration item) { ServiceDescriptor returnValue = null; if (item.ShouldCreate()) { // // Get the service type. // Type serviceType = item.FindType(TypeSource.Service); // // Get the implementation type. // Type implementationType = item.FindType(TypeSource.Implemenation); // // Check if the implementation type has any dependency properties. // IEnumerable <DependencyInfo> dependencyProperties = DependencyAttribute.GetDependencyProperties(implementationType); // // Select the lifetime. // ServiceLifetime lifetime = item.Lifetime == "Scoped" ? ServiceLifetime.Scoped : item.Lifetime == "Singleton" ? ServiceLifetime.Singleton : ServiceLifetime.Transient; // // Create the descriptor. // if (item.Properties == null && !dependencyProperties.Any()) { // // Standard definition. // returnValue = ServiceDescriptor.Describe(serviceType, implementationType, lifetime); } else { // // Factory based definition. // returnValue = ServiceDescriptor.Describe(serviceType, sp => (new DependencyFactory(implementationType, item, dependencyProperties)).GetInstance(sp), lifetime); } } return(returnValue); }
/// <summary> /// Adds data protection to web application's form /// </summary> /// <param name="services">IoC</param> /// <param name="options">Options</param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> public static IServiceCollection AddCuriosityDataProtection( this IServiceCollection services, DataProtectionOptions?options) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (options == null) { return(services); } if (options.IsEnabled) { options.AssertValid(); services.AddDataProtection() .SetApplicationName(options.ApplicationName) .DisableAutomaticKeyGeneration() // ReSharper disable once AssignNullToNotNullAttribute // already checked .PersistKeysToFileSystem(new DirectoryInfo(options.KeyRingPath)); } else { // if we do not need protection, then insert the stub var dataProtectionProviderDescriptor = services.FirstOrDefault(s => s.ServiceType == typeof(IDataProtectionProvider)); if (dataProtectionProviderDescriptor != null) { services.Replace( ServiceDescriptor.Describe( dataProtectionProviderDescriptor.ServiceType, sp => { var innerDataProtectionProvider = (IDataProtectionProvider)dataProtectionProviderDescriptor.ImplementationFactory(sp); return(new SecureLessDataProtectionProvider(innerDataProtectionProvider, options)); }, dataProtectionProviderDescriptor.Lifetime)); } } services.TryAddSingleton(options); return(services); }
private IServiceProvider ConfigureServices(IServiceCollection rootCollection) { var configuration = new ConfigurationBuilder().AddIniFile(_configFileLocation, false, ReloadConfigOnChange).Build(); var baseServiceType = typeof(BaseService); var serviceTypes = Assembly.GetEntryAssembly().GetTypes().Where(a => baseServiceType.IsAssignableFrom(a) && a.GetCustomAttribute <ServiceAttribute>() != null && !a.IsAbstract && a.GetCustomAttribute <ServiceAttribute>().AutoAdd).ToList(); foreach (var service in serviceTypes) { var serviceAttribute = service.GetCustomAttribute <ServiceAttribute>(); rootCollection.Add(ServiceDescriptor.Describe(service, service, serviceAttribute?.Lifetime ?? ServiceLifetime.Singleton)); } var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Add("User-Agent", nameof(LittleBigBot)); return(rootCollection .AddSingleton(new DiscordSocketClient(new DiscordSocketConfig { AlwaysDownloadUsers = true, MessageCacheSize = 100, LogLevel = LogSeverity.Verbose })) .AddSingleton(new CommandService(new CommandServiceConfiguration { CaseSensitive = false, DefaultRunMode = RunMode.Sequential, IgnoreExtraArguments = true, CooldownBucketKeyGenerator = new LittleBigBotCooldownBucketKeyGenerator() })) .AddLogging(log => { log.AddLittleBig(); }) .AddTransient <Random>() .AddSingleton(httpClient) .AddSingleton(services => { var options = services.GetRequiredService <IOptions <LittleBigBotConfig> >().Value.GitHub; return new GitHubClient(new ProductHeaderValue(options.Username), new InMemoryCredentialStore(new Credentials(options.Token))); }) .AddSingleton(this) .Configure <LittleBigBotConfig>(configuration.Bind) .BuildServiceProvider()); }