using Nop.Core.Domain.Customers; using Nop.Services.Customers; namespace Nop.Services.Plugins; /// /// Represents a plugin manager implementation /// /// Type of plugin public partial class PluginManager : IPluginManager where TPlugin : class, IPlugin { #region Fields protected readonly ICustomerService _customerService; protected readonly IPluginService _pluginService; protected readonly Dictionary> _plugins = new(); #endregion #region Ctor public PluginManager(ICustomerService customerService, IPluginService pluginService) { _customerService = customerService; _pluginService = pluginService; } #endregion #region Utilities /// /// Prepare the dictionary key to store loaded plugins /// /// Customer /// Store identifier /// Plugin system name /// /// A task that represents the asynchronous operation /// The task result contains the key /// protected virtual async Task GetKeyAsync(Customer customer, int storeId, string systemName = null) { return $"{storeId}-{(customer != null ? string.Join(',', await _customerService.GetCustomerRoleIdsAsync(customer)) : null)}-{systemName}"; } /// /// Load primary active plugin /// /// System name of primary active plugin /// Filter by customer; pass null to load all plugins /// Filter by store; pass 0 to load all plugins /// /// A task that represents the asynchronous operation /// The task result contains the plugin /// protected virtual async Task LoadPrimaryPluginAsync(string systemName, Customer customer = null, int storeId = 0) { //try to get a plugin by system name or return the first loaded one (it's necessary to have a primary active plugin) var plugin = await LoadPluginBySystemNameAsync(systemName, customer, storeId) ?? (await LoadAllPluginsAsync(customer, storeId)).FirstOrDefault(); return plugin; } #endregion #region Methods /// /// Load all plugins /// /// Filter by customer; pass null to load all plugins /// Filter by store; pass 0 to load all plugins /// /// A task that represents the asynchronous operation /// The task result contains the list of plugins /// public virtual async Task> LoadAllPluginsAsync(Customer customer = null, int storeId = 0) { //get plugins and put them into the dictionary to avoid further loading var key = await GetKeyAsync(customer, storeId); if (!_plugins.ContainsKey(key)) _plugins.Add(key, await _pluginService.GetPluginsAsync(customer: customer, storeId: storeId)); return _plugins[key]; } /// /// Load plugin by system name /// /// System name /// Filter by customer; pass null to load all plugins /// Filter by store; pass 0 to load all plugins /// /// A task that represents the asynchronous operation /// The task result contains the plugin /// public virtual async Task LoadPluginBySystemNameAsync(string systemName, Customer customer = null, int storeId = 0) { if (string.IsNullOrEmpty(systemName)) return null; //try to get already loaded plugin var key = await GetKeyAsync(customer, storeId, systemName); if (_plugins.TryGetValue(key, out var value)) return value.FirstOrDefault(); //or get it from list of all loaded plugins or load it for the first time var pluginBySystemName = _plugins.TryGetValue(await GetKeyAsync(customer, storeId), out var plugins) && plugins.FirstOrDefault(plugin => plugin.PluginDescriptor.SystemName.Equals(systemName, StringComparison.InvariantCultureIgnoreCase)) is TPlugin loadedPlugin ? loadedPlugin : (await _pluginService.GetPluginDescriptorBySystemNameAsync(systemName, customer: customer, storeId: storeId))?.Instance(); _plugins.Add(key, new List { pluginBySystemName }); return pluginBySystemName; } /// /// Load active plugins /// /// System names of active plugins /// Filter by customer; pass null to load all plugins /// Filter by store; pass 0 to load all plugins /// /// A task that represents the asynchronous operation /// The task result contains the list of active plugins /// public virtual async Task> LoadActivePluginsAsync(List systemNames, Customer customer = null, int storeId = 0) { if (systemNames == null) return new List(); //get loaded plugins according to passed system names return (await LoadAllPluginsAsync(customer, storeId)) .Where(plugin => systemNames.Contains(plugin.PluginDescriptor.SystemName, StringComparer.InvariantCultureIgnoreCase)) .ToList(); } /// /// Check whether the passed plugin is active /// /// Plugin to check /// System names of active plugins /// Result public virtual bool IsPluginActive(TPlugin plugin, List systemNames) { if (plugin == null) return false; return systemNames ?.Any(systemName => plugin.PluginDescriptor.SystemName.Equals(systemName, StringComparison.InvariantCultureIgnoreCase)) ?? false; } /// /// Get plugin logo URL /// /// Plugin /// /// A task that represents the asynchronous operation /// The task result contains the logo URL /// public virtual async Task GetPluginLogoUrlAsync(TPlugin plugin) { return await _pluginService.GetPluginLogoUrlAsync(plugin.PluginDescriptor); } #endregion }