namespace BotPages.Core.Abstractions;
///
/// Реализация , позволяющая регистрировать и разрешать несколько адаптеров.
///
public sealed class MultiAdapterFactory : IMessengerAdapterFactory
{
private readonly List _allAdapters = new();
private readonly Dictionary _adaptersById = new(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary> _adaptersByType = new(StringComparer.OrdinalIgnoreCase);
///
/// Список всех зарегистрированных адаптеров.
///
public IReadOnlyList AllAdapters => _allAdapters;
///
/// Зарегистрировать адаптер с уникальным идентификатором.
///
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();
_adaptersByType[adapterType] = typeList;
}
typeList.Add(adapter);
return this;
}
///
/// Зарегистрировать адаптер с автоматически сгенерированным ID.
///
public IMessengerAdapterFactory Register(IMessengerAdapterSetup adapter)
{
var adapterId = GenerateAdapterId(adapter);
return Register(adapterId, adapter);
}
///
/// Получить адаптер по ID.
///
public IMessengerAdapter Resolve(string adapterId)
{
if (_adaptersById.TryGetValue(adapterId, out var adapter))
{
return adapter;
}
throw new InvalidOperationException($"No adapter registered with ID '{adapterId}'");
}
///
/// Попытаться получить адаптер по ID.
///
public bool TryResolve(string adapterId, out IMessengerAdapter? adapter)
{
var result = _adaptersById.TryGetValue(adapterId, out var adapterSetup);
adapter = adapterSetup;
return result;
}
///
/// Получить все адаптеры определенного типа.
///
public IReadOnlyList GetAdaptersByType(string adapterType)
{
if (_adaptersByType.TryGetValue(adapterType, out var adapters))
{
return adapters.AsReadOnly();
}
return Array.Empty();
}
///
/// Проверить, зарегистрирован ли адаптер с указанным ID.
///
public bool Contains(string adapterId) => _adaptersById.ContainsKey(adapterId);
///
/// Удалить адаптер по ID.
///
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();
}
}