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));
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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);
                }
            }
        }
Beispiel #6
0
        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();
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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;