using System.Globalization; using Dalamud.Data; using Dalamud.Game; using Dalamud.Game.ClientState; using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Objects; using Dalamud.Game.Command; using Dalamud.Game.Gui; using Dalamud.Interface.Windowing; using Dalamud.Plugin; using Microsoft.Extensions.DependencyInjection; using Pal.Client.Commands; using Pal.Client.Configuration; using Pal.Client.Net; using Pal.Client.Properties; using Pal.Client.Rendering; using Pal.Client.Scheduled; using Pal.Client.Windows; namespace Pal.Client.DependencyInjection { /// /// DI-aware Plugin. /// // ReSharper disable once UnusedType.Global internal sealed class DependencyInjectionContext : IDalamudPlugin { private ServiceProvider? _serviceProvider; public string Name => Localization.Palace_Pal; public DependencyInjectionContext(DalamudPluginInterface pluginInterface, ClientState clientState, GameGui gameGui, ChatGui chatGui, ObjectTable objectTable, Framework framework, Condition condition, CommandManager commandManager, DataManager dataManager) { IServiceCollection services = new ServiceCollection(); // dalamud services.AddSingleton(this); services.AddSingleton(pluginInterface); services.AddSingleton(clientState); services.AddSingleton(gameGui); services.AddSingleton(chatGui); services.AddSingleton(objectTable); services.AddSingleton(framework); services.AddSingleton(condition); services.AddSingleton(commandManager); services.AddSingleton(dataManager); services.AddSingleton(new WindowSystem(typeof(DependencyInjectionContext).AssemblyQualifiedName)); // plugin-specific services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(sp => sp.GetRequiredService().Load()); services.AddTransient(); services.AddSingleton(); // territory handling services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // windows & related services services.AddSingleton(); services.AddSingleton(); services.AddTransient(); services.AddSingleton(); // these should maybe be scoped services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // queue handling services.AddTransient, QueuedImport.Handler>(); services.AddTransient, QueuedUndoImport.Handler>(); services.AddTransient, QueuedConfigUpdate.Handler>(); services.AddTransient, QueuedSyncResponse.Handler>(); // set up the current UI language before creating anything Localization.Culture = new CultureInfo(pluginInterface.UiLanguage); // build _serviceProvider = services.BuildServiceProvider(new ServiceProviderOptions { ValidateOnBuild = true, ValidateScopes = true, }); // initialize plugin #if RELEASE // You're welcome to remove this code in your fork, but please make sure that: // - none of the links accessible within FFXIV open the original repo (e.g. in the plugin installer), and // - you host your own server instance // // This is mainly to avoid this plugin being included in 'mega-repos' that, for whatever reason, decide // that collecting all plugins is a good idea (and break half in the process). _serviceProvider.GetService(); #endif // set up legacy services LocalState.PluginInterface = pluginInterface; LocalState.Mode = _serviceProvider.GetRequiredService().Mode; // windows that have logic to open on startup _serviceProvider.GetRequiredService(); // initialize components that are mostly self-contained/self-registered _serviceProvider.GetRequiredService(); _serviceProvider.GetRequiredService(); _serviceProvider.GetRequiredService(); _serviceProvider.GetRequiredService(); _serviceProvider.GetRequiredService(); } public void Dispose() { // ensure we're not calling dispose recursively on ourselves if (_serviceProvider != null) { ServiceProvider serviceProvider = _serviceProvider; _serviceProvider = null; serviceProvider.Dispose(); } } } }