Files
BotPages/BotPages.Core/Abstractions/MultiAdapterFactory.cs

128 lines
4.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace BotPages.Core.Abstractions;
/// <summary>
/// Реализация <see cref="IMessengerAdapterFactory"/>, позволяющая регистрировать и разрешать несколько адаптеров.
/// </summary>
public sealed class MultiAdapterFactory : IMessengerAdapterFactory
{
private readonly List<IMessengerAdapterSetup> _allAdapters = new();
private readonly Dictionary<string, IMessengerAdapterSetup> _adaptersById = new(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, List<IMessengerAdapterSetup>> _adaptersByType = new(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Список всех зарегистрированных адаптеров.
/// </summary>
public IReadOnlyList<IMessengerAdapterSetup> AllAdapters => _allAdapters;
/// <summary>
/// Зарегистрировать адаптер с уникальным идентификатором.
/// </summary>
public IMessengerAdapterFactory Register(string adapterId, IMessengerAdapterSetup adapter)
{
if (string.IsNullOrWhiteSpace(adapterId))
throw new ArgumentException("Adapter ID cannot be null or empty", nameof(adapterId));
if (_adaptersById.ContainsKey(adapterId))
throw new ArgumentException($"Adapter with ID '{adapterId}' is already registered", nameof(adapterId));
// Устанавливаем идентификатор в адаптер
adapter.SetAdapterId(adapterId);
_allAdapters.Add(adapter);
_adaptersById[adapterId] = adapter;
// Группируем по типу
var adapterType = adapter.Type;
if (!_adaptersByType.TryGetValue(adapterType, out var typeList))
{
typeList = new List<IMessengerAdapterSetup>();
_adaptersByType[adapterType] = typeList;
}
typeList.Add(adapter);
return this;
}
/// <summary>
/// Зарегистрировать адаптер с автоматически сгенерированным ID.
/// </summary>
public IMessengerAdapterFactory Register(IMessengerAdapterSetup adapter)
{
var adapterId = GenerateAdapterId(adapter);
return Register(adapterId, adapter);
}
/// <summary>
/// Получить адаптер по ID.
/// </summary>
public IMessengerAdapter Resolve(string adapterId)
{
if (_adaptersById.TryGetValue(adapterId, out var adapter))
{
return adapter;
}
throw new InvalidOperationException($"No adapter registered with ID '{adapterId}'");
}
/// <summary>
/// Попытаться получить адаптер по ID.
/// </summary>
public bool TryResolve(string adapterId, out IMessengerAdapter? adapter)
{
var result = _adaptersById.TryGetValue(adapterId, out var adapterSetup);
adapter = adapterSetup;
return result;
}
/// <summary>
/// Получить все адаптеры определенного типа.
/// </summary>
public IReadOnlyList<IMessengerAdapter> GetAdaptersByType(string adapterType)
{
if (_adaptersByType.TryGetValue(adapterType, out var adapters))
{
return adapters.AsReadOnly();
}
return Array.Empty<IMessengerAdapter>();
}
/// <summary>
/// Проверить, зарегистрирован ли адаптер с указанным ID.
/// </summary>
public bool Contains(string adapterId) => _adaptersById.ContainsKey(adapterId);
/// <summary>
/// Удалить адаптер по ID.
/// </summary>
public bool Remove(string adapterId)
{
if (_adaptersById.TryGetValue(adapterId, out var adapter))
{
_allAdapters.Remove(adapter);
_adaptersById.Remove(adapterId);
var adapterType = adapter.Type;
if (_adaptersByType.TryGetValue(adapterType, out var typeList))
{
typeList.Remove(adapter);
if (typeList.Count == 0)
{
_adaptersByType.Remove(adapterType);
}
}
return true;
}
return false;
}
private static string GenerateAdapterId(IMessengerAdapter adapter)
{
var adapterType = adapter.Type;
var guid = Guid.NewGuid().ToString("N").Substring(0, 8);
return $"{adapterType}_{guid}".ToLowerInvariant();
}
}