Files
PLib/src/PLib.Domain/Videos/LibraryLabel.cs
T

71 lines
2.2 KiB
C#

namespace PLib.Domain.Videos;
/// <summary>What a label is for; the relation to videos is identical either way.</summary>
public enum LabelKind
{
/// <summary>A free-form word used to narrow the grid down.</summary>
Tag,
/// <summary>A named group the user curates and browses as a whole.</summary>
Collection,
}
/// <summary>
/// A named grouping of videos — a tag or a collection.
/// </summary>
/// <remarks>
/// Tags and collections are the same relation: a name, many videos, a video in many of them.
/// They differ only in intent, and that intent is <see cref="Kind"/>. One entity means one
/// join table, one repository and one set of rules about naming; splitting them later is a
/// rename and a migration, whereas keeping two near-identical aggregates in sync from the
/// start is a permanent tax.
/// </remarks>
public sealed class LibraryLabel
{
private readonly List<VideoItem> _videos = [];
/// <summary>Required by EF Core materialization; do not use from application code.</summary>
private LibraryLabel()
{
Name = null!;
NormalizedName = null!;
}
public LibraryLabel(string name, LabelKind kind)
{
ArgumentException.ThrowIfNullOrWhiteSpace(name);
Id = Guid.CreateVersion7();
Kind = kind;
CreatedAt = DateTimeOffset.UtcNow;
Name = name.Trim();
NormalizedName = Normalize(name);
}
public Guid Id { get; private set; }
public string Name { get; private set; }
/// <summary>
/// Upper-cased, trimmed name. Uniqueness is enforced on this rather than on
/// <see cref="Name"/>, so "Комедия" and "комедия" cannot both exist.
/// </summary>
public string NormalizedName { get; private set; }
public LabelKind Kind { get; private set; }
public DateTimeOffset CreatedAt { get; private set; }
public IReadOnlyCollection<VideoItem> Videos => _videos;
public static string Normalize(string name) => name.Trim().ToUpperInvariant();
public void Rename(string name)
{
ArgumentException.ThrowIfNullOrWhiteSpace(name);
Name = name.Trim();
NormalizedName = Normalize(name);
}
}