Пример #1
0
        /// <summary>
        /// Составляем приложение.
        /// </summary>
        /// <param name="startupConfiguration">Параметры запуска приложения.</param>
        /// <returns>Провайдер к коллекции зарегистрированных сервисов.</returns>
        public IBuildContext Build(StartupConfiguration startupConfiguration)
        {
            _buildContext = new BuildContext {
                StartupConfiguration = startupConfiguration,
            };
            var measureSession = new MeasureSession("Конфигурирование служб");

            // Разбор параметров командной строки
            startupConfiguration.BuildUpFromCommandLineArgs(startupConfiguration.CommandLineArgs.Args);

            // Can use defined service collection or create new
            _buildContext.ServiceCollection = startupConfiguration.ServiceCollection ?? new ServiceCollection();
            var serviceCollection = _buildContext.ServiceCollection;

            using (measureSession.StartTimer("ConfigureLogging"))
            {
                // Установка путей логирования, создание и блокирование pid-файла
                // todo: UseCentralizedLogging
                var unlocker = LoggingExtensions.SetupLogsPath(startupConfiguration);
                serviceCollection.AddSingleton(unlocker);

                // Получение сконфигурированной фабрики логирования.
                var configureLogging = startupConfiguration.ConfigureLogging ?? DefaultLogging.ConfigureLogging;
                _buildContext.LoggerFactory = configureLogging();
                _buildContext.Logger        = _buildContext.LoggerFactory.CreateLogger("Bootstrap");
            }

            using (measureSession.StartTimer("LoadTypes"))
            {
                // Получение информации об окружении.
                _buildContext.StartupInfo = ReflectionUtils.GetStartupInfo();

                // Переключим текущую директорию на директорию запуска.
                Directory.SetCurrentDirectory(_buildContext.StartupInfo.BaseDirectory);
                _buildContext.StartupInfo.CurrentDirectory = _buildContext.StartupInfo.BaseDirectory;

                // Загрузка сборок в память
                _buildContext.Assemblies = ReflectionUtils
                                           .LoadAssemblies(_buildContext.StartupInfo.BaseDirectory, _buildContext.StartupConfiguration.AssemblyScanPatterns)
                                           .Concat(new[] { typeof(ApplicationBuilder).Assembly })
                                           .ToArray();

                _buildContext.Logger.LogDebug($"Loaded {_buildContext.Assemblies.Length} assemblies");

                if (_buildContext.Assemblies.Length > 20)
                {
                    var assemblyScanPatterns     = _buildContext.StartupConfiguration.AssemblyScanPatterns;
                    var assemblyScanPatternsText = string.Join(",", assemblyScanPatterns);
                    _buildContext.Logger.LogWarning($"Diagnostic: too many assemblies found. Specify AssemblyScanPatterns. Loaded: {_buildContext.Assemblies.Length} assemblies, AssemblyScanPatterns: {assemblyScanPatternsText}");
                }

                // Список типов
                _buildContext.ExportedTypes = _buildContext.Assemblies.SelectMany(assembly => assembly.GetDefinedTypesSafe()).ToArray();

                _buildContext.LogHeader();//todo: assemblies loaded? types loaded
            }

            using (measureSession.StartTimer("LoadConfiguration"))
            {
                // Загрузка конфигурации
                new LoadConfiguration().Execute(_buildContext);

                // Регистрируем конфигурацию в виде IConfiguration и IConfigurationRoot
                serviceCollection.Replace(ServiceDescriptor.Singleton <IConfiguration>(_buildContext.ConfigurationRoot));
                serviceCollection.Replace(ServiceDescriptor.Singleton <IConfigurationRoot>(_buildContext.ConfigurationRoot));

                // Dump значений конфигурации в лог
                if (startupConfiguration.DumpConfigurationToLog)
                {
                    _buildContext.ConfigurationRoot.DumpConfigurationToLog(_buildContext.LoggerFactory);
                }
            }

            using (measureSession.StartTimer("ConfigureServices"))
            {
                try
                {
                    // Конфигурирование сервисов
                    ConfigureServices(_buildContext);

                    // Строим провайдер.
                    _buildContext.ServiceProvider = _buildContext.ServiceCollection.BuildServiceProvider();

                    if (startupConfiguration.ExternalBuilder != null)
                    {
                        _buildContext.ServiceProvider = ConfigureServicesExt(_buildContext);
                    }
                }
                catch (Exception exception)
                {
                    //todo: right logging
                    _buildContext.Logger.LogError(new EventId(0), exception, exception.Message);
                    throw;
                }
            }



            measureSession.LogMeasures(_buildContext.Logger);

            return(_buildContext);
        }