// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.OpenMU.PlugIns; using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Logging; /// /// The implementation for the which provides plugins by their key. /// /// The type of the key. /// The type of the plugin. /// /// public class StrategyPlugInProvider : PlugInContainerBase, IStrategyPlugInProvider where TPlugIn : class, IStrategyPlugIn where TKey : notnull { private readonly IDictionary _effectiveStrategies = new Dictionary(); /// /// Initializes a new instance of the class. /// /// The plugin manager that manages this instance. /// The logger factory. public StrategyPlugInProvider(PlugInManager manager, ILoggerFactory loggerFactory) : base(manager) { this.Logger = loggerFactory.CreateLogger(this.GetType()); } /// public IEnumerable AvailableStrategies { get { using var l = this.Lock.ReaderLock(); return this._effectiveStrategies.Values.ToList(); } } /// /// Gets the logger. /// /// /// The logger. /// protected ILogger Logger { get; } /// public TPlugIn? this[TKey key] { get { using var l = this.Lock.ReaderLock(); if (this.TryGetPlugIn(key, out var plugIn)) { return plugIn; } return default; } } /// /// Tries the get the plug in with the specified key. /// /// The key. /// The plugin. /// True, if the plugin has been found and returned; Otherwise, false. protected bool TryGetPlugIn(TKey key, [MaybeNullWhen(false)] out TPlugIn plugIn) => this._effectiveStrategies.TryGetValue(key, out plugIn); /// protected override void ActivatePlugIn(TPlugIn plugIn) { base.ActivatePlugIn(plugIn); if (this._effectiveStrategies.TryGetValue(plugIn.Key, out var registeredPlugIn)) { this.Logger.LogWarning($"Plugin {registeredPlugIn} with key {plugIn.Key} was already registered and is active. Plugin {plugIn} will not be effective."); } else { this.SetEffectivePlugin(plugIn); } } /// protected override void DeactivatePlugIn(TPlugIn plugIn) { base.DeactivatePlugIn(plugIn); if (this._effectiveStrategies.TryGetValue(plugIn.Key, out var effective) && effective == plugIn) { this._effectiveStrategies.Remove(plugIn.Key); } } /// /// Sets the effective plugin. /// /// The plugin. protected void SetEffectivePlugin(TPlugIn plugIn) { this._effectiveStrategies.Remove(plugIn.Key); this._effectiveStrategies.Add(plugIn.Key, plugIn); } }