public static object?Create(this ConfigurationInstanceHolder holder, Type type) { var instances = holder.GetInstances(type); if (instances.Count == 1) { return(instances.Values.FirstOrDefault()); } if (instances.Count > 1) { throw new InvalidOperationException($"Found multiple instances of type {type.FullName}"); } var constructors = type.GetConstructors(); if (constructors.Length != 1) { throw new InvalidOperationException($"The type {type.FullName} has multiple constructors"); } var constructorInfo = constructors[0]; var parameters = constructorInfo.GetParameters(); var missingArgs = parameters.Where(p => !holder.RegisteredTypes.Any(registeredType => p.ParameterType.IsAssignableFrom(registeredType)) && !p.IsOptional).ToArray(); var optionalArgs = parameters.Where(p => !holder.RegisteredTypes.Any(registeredType => p.ParameterType.IsAssignableFrom(registeredType)) && p.IsOptional).ToArray(); if (missingArgs.Length > 0) { throw new InvalidOperationException( $"Missing types defined in ctor for type {type.FullName}: {string.Join(", ", missingArgs.Select(m => m.ParameterType.FullName))}"); } object?GetArgumentValue(ParameterInfo parameter) { object?value = optionalArgs.Contains(parameter) ? null : holder.GetInstances( holder.RegisteredTypes.Single(reg => parameter.ParameterType.IsAssignableFrom(reg))) .Single() .Value; return(value); } object?[] args = parameters.Length == 0 ? Array.Empty <object>() : parameters.Select(GetArgumentValue).ToArray(); return(Activator.CreateInstance(type, args)); }
public static IServiceCollection AddConfigurationInstanceHolder( this IServiceCollection services, ConfigurationInstanceHolder holder) { foreach (Type holderRegisteredType in holder.RegisteredTypes) { var genericType = typeof(INamedInstance <>).MakeGenericType(holderRegisteredType); foreach (KeyValuePair <string, object> instance in holder.GetInstances(holderRegisteredType)) { services.Add(new ServiceDescriptor(holderRegisteredType, provider => instance.Value, ServiceLifetime.Transient)); var concreteGenericType = typeof(NamedInstance <>).MakeGenericType(holderRegisteredType); services.Add(new ServiceDescriptor(genericType, provider => Activator.CreateInstance(concreteGenericType, instance.Value, instance.Key) ?? throw new InvalidOperationException( $"Could not create type {concreteGenericType.FullName}"), ServiceLifetime.Transient)); } } return(services); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { _stoppingToken = stoppingToken; stoppingToken.Register(() => { foreach (var cancellationTokenSource in _cancellations) { if (!cancellationTokenSource.Value.IsCancellationRequested) { cancellationTokenSource.Value.Cancel(); } } }); await Task.Yield(); _workers = _configurationInstanceHolder.GetInstances <DeploymentTargetWorker>().Values .NotNull() .ToList(); foreach (var deploymentTargetWorker in _workers) { StartWorker(deploymentTargetWorker, stoppingToken); } while (!stoppingToken.IsCancellationRequested) { try { var completedTaskKeys = _tasks .Where(pair => pair.Value.IsCompletedSuccessfully) .Select(pair => pair.Key) .ToArray(); foreach (var completedTaskKey in completedTaskKeys) { if (_tasks.ContainsKey(completedTaskKey)) { _tasks.Remove(completedTaskKey); } } } catch (Exception ex) { _logger.Error(ex, "Could not clean up completed worker tasks"); } await stoppingToken; } await Task.WhenAll(_tasks.Values.Where(task => !task.IsCompleted)); }
public void WhenRegisteringSingleInstance() { var holder = new ConfigurationInstanceHolder(); holder.Add(new NamedInstance <ValidatableOptional>(new ValidatableOptional("abc", 123), "abc-instance")); ImmutableDictionary <string, ValidatableOptional?> instances = holder.GetInstances <ValidatableOptional>(); Assert.Single(instances); Assert.Equal("abc-instance", instances.Keys.Single()); Assert.Equal("abc", instances["abc-instance"].Name); Assert.Equal(123, instances["abc-instance"].Value); }
public static IEnumerable <T> CreateInstances <T>(this ConfigurationInstanceHolder holder) where T : class { var registeredTypes = holder.RegisteredTypes .Where(registered => typeof(T).IsAssignableFrom(registered) && !registered.IsAbstract) .ToArray(); foreach (Type registeredType in registeredTypes) { foreach (T instance in holder.GetInstances(registeredType).Values.OfType <T>()) { yield return(instance); } } }
private static Task <App <T> > BuildAppAsync(CancellationTokenSource cancellationTokenSource, string[] commandLineArgs, IReadOnlyDictionary <string, string> environmentVariables, IReadOnlyCollection <Assembly> scanAssemblies, params object[] instances) { MultiSourceKeyValueConfiguration startupConfiguration = ConfigurationInitialization.InitializeStartupConfiguration(commandLineArgs, environmentVariables, scanAssemblies); ConfigurationInstanceHolder configurationInstanceHolder = GetConfigurationRegistrations(startupConfiguration, scanAssemblies); var assemblyResolver = new InstanceApplicationAssemblyResolver(scanAssemblies.SafeToImmutableArray()); configurationInstanceHolder.AddInstance(assemblyResolver); configurationInstanceHolder.AddInstance(configurationInstanceHolder); foreach (object instance in instances.NotNull()) { configurationInstanceHolder.AddInstance(instance); } var loggingLevelSwitch = new LoggingLevelSwitch(); configurationInstanceHolder.AddInstance(loggingLevelSwitch); configurationInstanceHolder.AddInstance(cancellationTokenSource); ApplicationPaths paths = configurationInstanceHolder.GetInstances <ApplicationPaths>().SingleOrDefault().Value ?? new ApplicationPaths(); AppPathHelper.SetApplicationPaths(paths, commandLineArgs); if (paths.BasePath is null) { throw new InvalidOperationException("Base path is not set"); } var startupLoggerConfigurationHandlers = assemblyResolver.GetAssemblies() .GetLoadablePublicConcreteTypesImplementing < IStartupLoggerConfigurationHandler>() .Select(type => configurationInstanceHolder.Create(type) as IStartupLoggerConfigurationHandler) .Where(item => item is { }).ToImmutableArray();
public void WhenRegisteringMultipleInstances() { var holder = new ConfigurationInstanceHolder(); holder.Add(new NamedInstance <ValidatableOptional>(new ValidatableOptional("abc", 123), "abc-instance")); holder.Add(new NamedInstance <ValidatableOptional>(new ValidatableOptional("def", 234), "def-instance")); ImmutableDictionary <string, ValidatableOptional?> instances = holder.GetInstances <ValidatableOptional>(); Assert.Equal(2, instances.Count); Assert.Contains("abc-instance", instances.Keys); Assert.Equal("abc", instances["abc-instance"].Name); Assert.Equal(123, instances["abc-instance"].Value); Assert.Contains("def-instance", instances.Keys); Assert.Equal("def", instances["def-instance"].Name); Assert.Equal(234, instances["def-instance"].Value); }
public object Diagnostics( [FromServices] ConfigurationInstanceHolder configurationInstanceHolder, [FromServices] IEnumerable <MySampleMultipleInstance> multipleInstances) { if (configurationInstanceHolder is null) { throw new ArgumentNullException(nameof(configurationInstanceHolder)); } if (multipleInstances is null) { throw new ArgumentNullException(nameof(multipleInstances)); } return(new { Instances = configurationInstanceHolder !.RegisteredTypes .Select(type => new { type.FullName, Instances = configurationInstanceHolder.GetInstances(type).ToArray() }) .ToArray(), multipleInstances });
public static T?Get <T>(this ConfigurationInstanceHolder holder) where T : class => holder.GetInstances <T>().SingleOrDefault().Value;