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