public async Task <IHost> InitAsync( List <Assembly> openModHostAssemblies, RuntimeInitParameters parameters, Func <IHostBuilder>?hostBuilderFunc = null) { if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } HostAssemblies = openModHostAssemblies ?? throw new ArgumentNullException(nameof(openModHostAssemblies)); try { IsDisposing = false; var openModCoreAssembly = typeof(AsyncHelper).Assembly; if (!openModHostAssemblies.Contains(openModCoreAssembly)) { openModHostAssemblies.Insert(0, openModCoreAssembly); } var hostInformationType = openModHostAssemblies .Select(asm => AssemblyExtensions.GetLoadableTypes(asm) .FirstOrDefault(t => typeof(IHostInformation).IsAssignableFrom(t))) .LastOrDefault(d => d != null); if (hostInformationType == null) { throw new Exception("Failed to find IHostInformation in host assemblies."); } HostInformation = (IHostInformation)Activator.CreateInstance(hostInformationType); m_OpenModHostAssemblies = openModHostAssemblies; m_HostBuilderFunc = hostBuilderFunc; m_RuntimeInitParameters = parameters; var hostBuilder = hostBuilderFunc == null ? new HostBuilder() : hostBuilderFunc(); if (!Directory.Exists(parameters.WorkingDirectory)) { Directory.CreateDirectory(parameters.WorkingDirectory); } Status = RuntimeStatus.Initializing; WorkingDirectory = parameters.WorkingDirectory; CommandlineArgs = parameters.CommandlineArgs; SetupSerilog(false); m_Logger.LogInformation("OpenMod v{Version} is starting...", Version); if (parameters.PackageManager is not NuGetPackageManager nugetPackageManager) { var packagesDirectory = Path.Combine(WorkingDirectory, "packages"); nugetPackageManager = new NuGetPackageManager(packagesDirectory); } nugetPackageManager.Logger = new OpenModNuGetLogger(m_LoggerFactory !.CreateLogger("NuGet")); await nugetPackageManager.RemoveOutdatedPackagesAsync(); nugetPackageManager.InstallAssemblyResolver(); nugetPackageManager.SetAssemblyLoader((NuGetPackageManager.AssemblyLoader)Hotloader.LoadAssembly); var startupContext = new OpenModStartupContext { Runtime = this, LoggerFactory = m_LoggerFactory !, NuGetPackageManager = nugetPackageManager, DataStore = new Dictionary <string, object>() }; var startup = new OpenModStartup(startupContext); startupContext.OpenModStartup = startup; foreach (var assembly in openModHostAssemblies) { startup.RegisterIocAssemblyAndCopyResources(assembly, string.Empty); } var configFile = Path.Combine(WorkingDirectory, "openmod.yaml"); if (File.Exists(configFile)) { var yaml = File.ReadAllText(configFile); var deserializer = new DeserializerBuilder() .WithTypeConverter(new YamlNullableEnumTypeConverter()) .WithNamingConvention(CamelCaseNamingConvention.Instance) .Build(); var config = deserializer.Deserialize <Dictionary <string, object> >(yaml); var hotReloadingEnabled = true; if (config.TryGetValue("hotreloading", out var unparsed)) { switch (unparsed) { case bool value: hotReloadingEnabled = value; break; case string strValue when bool.TryParse(strValue, out var parsed): hotReloadingEnabled = parsed; break; default: m_Logger.LogWarning( "Unknown config for 'hotreloading' in OpenMod configuration: {UnparsedConfig}", unparsed); break; } } Hotloader.Enabled = hotReloadingEnabled; var tryInstallMissingDependencies = false; if (config.TryGetValue("nuget", out unparsed) && unparsed is Dictionary <object, object> nugetConfig) { if (nugetConfig.TryGetValue("tryAutoInstallMissingDependencies", out unparsed)) { switch (unparsed) { case bool value: tryInstallMissingDependencies = value; break; case string strValue when bool.TryParse(strValue, out var parsed): tryInstallMissingDependencies = parsed; break; default: m_Logger.LogWarning( "Unknown config for 'tryAutoInstallMissingDependencies' in OpenMod configuration: {UnparsedConfig}", unparsed); break; } } } PluginAssemblyStore.TryInstallMissingDependencies = tryInstallMissingDependencies; } await nugetPackageManager.InstallMissingPackagesAsync(updateExisting : true); await startup.LoadPluginAssembliesAsync(); SetupSerilog(true); hostBuilder .UseContentRoot(parameters.WorkingDirectory) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureHostConfiguration(builder => { ConfigureConfiguration(builder, startup); ((OpenModStartupContext)startup.Context).Configuration = builder.Build(); }) .ConfigureAppConfiguration(builder => ConfigureConfiguration(builder, startup)) .ConfigureContainer <ContainerBuilder>(builder => SetupContainer(builder, startup)) .ConfigureServices(services => SetupServices(services, startup)) .UseSerilog(); Host = hostBuilder.Build(); m_AppLifeTime = Host.Services.GetRequiredService <IHostApplicationLifetime>(); m_AppLifeTime.ApplicationStopping.Register(() => { AsyncHelper.RunSync(ShutdownAsync); }); Status = RuntimeStatus.Initialized; LifetimeScope = Host.Services.GetRequiredService <ILifetimeScope>().BeginLifetimeScopeEx( containerBuilder => { containerBuilder.Register(_ => this) .As <IOpenModComponent>() .SingleInstance() .ExternallyOwned(); containerBuilder.RegisterType <ScopedPermissionChecker>() .As <IPermissionChecker>() .InstancePerLifetimeScope() .OwnedByLifetimeScope(); }); DataStore = Host.Services.GetRequiredService <IDataStoreFactory>().CreateDataStore( new DataStoreCreationParameters { Component = this, Prefix = "openmod", Suffix = null, WorkingDirectory = WorkingDirectory }); try { await Host.StartAsync(); } catch (Exception ex) { Status = RuntimeStatus.Crashed; m_Logger.LogCritical(ex, "OpenMod has crashed"); Log.CloseAndFlush(); } PerformFileSystemWatcherPatch(); return(Host); } catch (Exception ex) { Console.WriteLine(ex); throw; } }