namespace BotPages.Core { /// /// Базовая реализация реестра страниц на словаре. /// public sealed class PageRegistry : IPageRegistry { private readonly Dictionary _pages = new(StringComparer.Ordinal); private readonly IPage _defaultPage; /// /// Создаёт реестр из набора страниц. /// public PageRegistry(IEnumerable pages) : this(pages, pages.First()) { } /// /// Создаёт реестр из набора страниц. /// public PageRegistry(IEnumerable pages, IPage defaultPage) { foreach (var p in pages) _pages[p.Id] = p; _defaultPage = defaultPage; } /// /// Возвращает страницу по идентификатору. /// public IPage Get(string id) => _pages[id]; /// /// Возвращает страницу по идентификатору. Если страницы нет, возвращает дефолтную. /// public IPage GetOrDefault(string id) => _pages.TryGetValue(id, out var page) ? page : _defaultPage; /// /// Возвращает дефолтную страницу. /// public IPage DefaultPage => _defaultPage; /// /// Пытается получить страницу по идентификатору. /// public bool TryGet(string id, out IPage? page) => _pages.TryGetValue(id, out page); /// /// Возвращает все зарегистрированные страницы. /// public IEnumerable All() => _pages.Values; /// /// Создаёт реестр страниц из всех сборок приложения. /// public static PageRegistry CreateFromApplication(string? defaultPageId = null) { // Берём все загруженные сборки в текущем AppDomain var assemblies = AppDomain.CurrentDomain.GetAssemblies(); // Находим все классы, реализующие IPage var pages = assemblies .SelectMany(a => a.GetTypes()) .Where(t => typeof(IPage).IsAssignableFrom(t) && !t.IsAbstract && t.GetConstructor(Type.EmptyTypes) != null) .Select(t => (IPage)Activator.CreateInstance(t)!) .ToList(); if (pages.Count == 0) throw new InvalidOperationException($"В приложении не найдено ни одной страницы ({nameof(IPage)})."); // Определяем страницу по умолчанию var defaultPage = defaultPageId != null ? pages.FirstOrDefault(p => p.Id == defaultPageId) : pages.First(); if (defaultPage == null) throw new InvalidOperationException($"Не найдена страница с Id={defaultPageId}."); return new PageRegistry(pages, defaultPage); } } }