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