/// <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); }