Доработан Docking
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
/// <summary>
|
||||
/// Реестр типов содержимого, который позволяет создавать экземпляры контента по типу.
|
||||
/// Этот сервис является центральным для динамического создания панелей инструментов и документов в IDE.
|
||||
/// Этот сервис является центральным для динамического создания панелей инструментов и документов.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Реализует шаблон "Фабрика" для создания экземпляров <see cref="Abstractions.IDockContent"/>.
|
||||
@@ -16,12 +16,19 @@ public class ContentRegistry
|
||||
/// <summary>
|
||||
/// Регистрирует фабричный метод для создания контента указанного типа.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Тип контента, реализующий <see cref="Abstractions.IDockContent"/>.</typeparam>
|
||||
/// <typeparam name="T">
|
||||
/// Тип контента, реализующий <see cref="Abstractions.IDockContent"/>.
|
||||
/// </typeparam>
|
||||
/// <param name="contentTypeId">Уникальный идентификатор типа контента.</param>
|
||||
/// <param name="factory">Фабричный метод для создания экземпляров контента.</param>
|
||||
/// <param name="metadata">Метаданные типа контента (опционально).</param>
|
||||
/// <exception cref="ArgumentNullException">Выбрасывается, если contentTypeId или factory равны null.</exception>
|
||||
/// <exception cref="ArgumentException">Выбрасывается, если contentTypeId уже зарегистрирован.</exception>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Выбрасывается, если <paramref name="contentTypeId"/> или <paramref name="factory"/>
|
||||
/// равны null.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Выбрасывается, если <paramref name="contentTypeId"/> уже зарегистрирован.
|
||||
/// </exception>
|
||||
public void Register<T>(string contentTypeId, Func<T> factory, ContentMetadata? metadata = null)
|
||||
where T : Abstractions.IDockContent
|
||||
{
|
||||
@@ -31,7 +38,7 @@ public class ContentRegistry
|
||||
throw new ArgumentNullException(nameof(factory));
|
||||
|
||||
if (_contentTypes.ContainsKey(contentTypeId))
|
||||
throw new ArgumentException($"Content type '{contentTypeId}' is already registered.");
|
||||
throw new ArgumentException($"Тип контента '{contentTypeId}' уже зарегистрирован.");
|
||||
|
||||
_contentTypes[contentTypeId] = new ContentDescriptor(
|
||||
typeof(T),
|
||||
@@ -45,14 +52,25 @@ public class ContentRegistry
|
||||
/// </summary>
|
||||
/// <param name="contentTypeId">Идентификатор типа контента.</param>
|
||||
/// <param name="id">Уникальный идентификатор для создаваемого экземпляра контента.</param>
|
||||
/// <returns>Новый экземпляр контента.</returns>
|
||||
/// <exception cref="KeyNotFoundException">Выбрасывается, если тип контента не зарегистрирован.</exception>
|
||||
/// <returns>
|
||||
/// Новый экземпляр контента.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Выбрасывается, если <paramref name="contentTypeId"/> равен null или пустой строке.
|
||||
/// </exception>
|
||||
/// <exception cref="KeyNotFoundException">
|
||||
/// Выбрасывается, если тип контента не зарегистрирован.
|
||||
/// </exception>
|
||||
public Abstractions.IDockContent CreateContent(string contentTypeId, string id)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(contentTypeId))
|
||||
throw new ArgumentNullException(nameof(contentTypeId));
|
||||
|
||||
if (!_contentTypes.TryGetValue(contentTypeId, out var descriptor))
|
||||
throw new KeyNotFoundException($"Content type '{contentTypeId}' is not registered.");
|
||||
throw new KeyNotFoundException($"Тип контента '{contentTypeId}' не зарегистрирован.");
|
||||
|
||||
var content = descriptor.Factory();
|
||||
|
||||
// Устанавливаем ID через рефлексию, если есть свойство Id
|
||||
var property = content.GetType().GetProperty("Id");
|
||||
if (property != null && property.CanWrite)
|
||||
@@ -67,9 +85,14 @@ public class ContentRegistry
|
||||
/// Получает метаданные для указанного типа контента.
|
||||
/// </summary>
|
||||
/// <param name="contentTypeId">Идентификатор типа контента.</param>
|
||||
/// <returns>Метаданные типа контента или null, если тип не найден.</returns>
|
||||
/// <returns>
|
||||
/// Метаданные типа контента или null, если тип не найден.
|
||||
/// </returns>
|
||||
public ContentMetadata? GetMetadata(string contentTypeId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(contentTypeId))
|
||||
return null;
|
||||
|
||||
return _contentTypes.TryGetValue(contentTypeId, out var descriptor)
|
||||
? descriptor.Metadata
|
||||
: null;
|
||||
@@ -78,24 +101,54 @@ public class ContentRegistry
|
||||
/// <summary>
|
||||
/// Получает все зарегистрированные типы контента.
|
||||
/// </summary>
|
||||
/// <returns>Коллекция идентификаторов зарегистрированных типов контента.</returns>
|
||||
/// <returns>
|
||||
/// Коллекция идентификаторов зарегистрированных типов контента.
|
||||
/// </returns>
|
||||
public IEnumerable<string> GetRegisteredTypes() => _contentTypes.Keys;
|
||||
|
||||
/// <summary>
|
||||
/// Проверяет, зарегистрирован ли указанный тип контента.
|
||||
/// </summary>
|
||||
public bool IsRegistered(string contentTypeId) => _contentTypes.ContainsKey(contentTypeId);
|
||||
/// <param name="contentTypeId">Идентификатор типа контента.</param>
|
||||
/// <returns>
|
||||
/// true, если тип контента зарегистрирован; в противном случае false.
|
||||
/// </returns>
|
||||
public bool IsRegistered(string contentTypeId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(contentTypeId))
|
||||
return false;
|
||||
|
||||
return _contentTypes.ContainsKey(contentTypeId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Дескриптор типа контента, содержащий информацию о фабричном методе и метаданных.
|
||||
/// Представляет дескриптор типа контента, содержащий информацию о фабричном методе и метаданных.
|
||||
/// </summary>
|
||||
private class ContentDescriptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Получает тип контента.
|
||||
/// </summary>
|
||||
public Type ContentType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Получает фабричный метод для создания экземпляров контента.
|
||||
/// </summary>
|
||||
public Func<Abstractions.IDockContent> Factory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Получает метаданные типа контента.
|
||||
/// </summary>
|
||||
public ContentMetadata Metadata { get; }
|
||||
|
||||
public ContentDescriptor(Type contentType, Func<Abstractions.IDockContent> factory, ContentMetadata metadata)
|
||||
/// <summary>
|
||||
/// Инициализирует новый экземпляр класса <see cref="ContentDescriptor"/>.
|
||||
/// </summary>
|
||||
/// <param name="contentType">Тип контента.</param>
|
||||
/// <param name="factory">Фабричный метод.</param>
|
||||
/// <param name="metadata">Метаданные.</param>
|
||||
public ContentDescriptor(Type contentType, Func<Abstractions.IDockContent> factory,
|
||||
ContentMetadata metadata)
|
||||
{
|
||||
ContentType = contentType;
|
||||
Factory = factory;
|
||||
@@ -105,54 +158,80 @@ public class ContentRegistry
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Метаданные типа контента, предоставляющие дополнительную информацию для отображения в UI.
|
||||
/// Представляет метаданные типа контента, предоставляющие дополнительную информацию для отображения в UI.
|
||||
/// </summary>
|
||||
public class ContentMetadata
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор типа контента.
|
||||
/// Получает идентификатор типа контента.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Уникальный строковый идентификатор типа контента.
|
||||
/// </value>
|
||||
public string ContentTypeId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Отображаемое имя типа контента.
|
||||
/// Получает или задает отображаемое имя типа контента.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Имя типа контента, отображаемое пользователю.
|
||||
/// </value>
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Описание типа контента.
|
||||
/// Получает или задает описание типа контента.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Текстовое описание функциональности контента.
|
||||
/// </value>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Имя ресурса для иконки (опционально).
|
||||
/// Получает или задает имя ресурса для иконки типа контента.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Имя ресурса иконки или null, если иконка не определена.
|
||||
/// </value>
|
||||
public string? IconResource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Признак того, что контент является документом (а не инструментальной панелью).
|
||||
/// Получает или задает значение, указывающее, является ли контент документом
|
||||
/// (а не инструментальной панелью).
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// true, если контент является документом; в противном случае false.
|
||||
/// </value>
|
||||
public bool IsDocument { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Минимальная ширина контента в пикселях.
|
||||
/// Получает или задает ширину контента по умолчанию.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Ширина контента в пикселях. Значение по умолчанию: 300.
|
||||
/// </value>
|
||||
public double DefaultWidth { get; set; } = 300;
|
||||
|
||||
/// <summary>
|
||||
/// Минимальная высота контента в пикселях.
|
||||
/// Получает или задает высоту контента по умолчанию.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Высота контента в пикселях. Значение по умолчанию: 200.
|
||||
/// </value>
|
||||
public double DefaultHeight { get; set; } = 200;
|
||||
|
||||
/// <summary>
|
||||
/// Инициализирует новый экземпляр метаданных контента.
|
||||
/// Инициализирует новый экземпляр класса <see cref="ContentMetadata"/>.
|
||||
/// </summary>
|
||||
/// <param name="contentTypeId">Идентификатор типа контента.</param>
|
||||
/// <param name="displayName">Отображаемое имя.</param>
|
||||
/// <param name="displayName">Отображаемое имя типа контента.</param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Выбрасывается, если <paramref name="contentTypeId"/> или <paramref name="displayName"/>
|
||||
/// равны null.
|
||||
/// </exception>
|
||||
public ContentMetadata(string contentTypeId, string displayName)
|
||||
{
|
||||
ContentTypeId = contentTypeId;
|
||||
DisplayName = displayName;
|
||||
ContentTypeId = contentTypeId ?? throw new ArgumentNullException(nameof(contentTypeId));
|
||||
DisplayName = displayName ?? throw new ArgumentNullException(nameof(displayName));
|
||||
Description = string.Empty;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user