Перепиливание под чистый DDD
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Knot.Shared.Kernel;
|
||||
|
||||
namespace Knot.Modules.Messaging.Domain;
|
||||
|
||||
/// <summary>
|
||||
/// Абстрактная база агрегата Сообщение.
|
||||
/// </summary>
|
||||
public abstract class Message : AggregateRoot<Guid>
|
||||
{
|
||||
// ================== Базовые поля ==================
|
||||
public Guid ChatId { get; protected set; }
|
||||
public Guid SenderId { get; protected set; }
|
||||
public DateTime CreatedAt { get; protected set; }
|
||||
public long SequenceId { get; protected set; }
|
||||
|
||||
public void SetSequenceId(long sequenceId)
|
||||
{
|
||||
SequenceId = sequenceId;
|
||||
}
|
||||
// ================== Опциональные метаданные (общего назначения) ==================
|
||||
public Guid? ReplyToId { get; protected set; }
|
||||
public Guid? ForwardedFromId { get; protected set; }
|
||||
|
||||
// ================== Флаги ==================
|
||||
public MessageState State { get; protected set; }
|
||||
|
||||
// ================== Абстрактные / Виртуальные свойства ==================
|
||||
public abstract string Type { get; }
|
||||
public abstract string? Content { get; protected set; }
|
||||
|
||||
public virtual string? Quote { get; protected set; } = null;
|
||||
public virtual Guid? StoryId => null;
|
||||
public virtual string? StoryMediaUrl => null;
|
||||
public virtual string? StoryMediaType => null;
|
||||
public virtual IReadOnlyCollection<Media> Media => Array.Empty<Media>();
|
||||
|
||||
public bool IsEdited => HasState(MessageState.IsEdited);
|
||||
public bool IsDeleted => HasState(MessageState.IsDeleted);
|
||||
public bool IsDeletedForUser(Guid userId) => _deletedFor.Exists(d => d.UserId == userId);
|
||||
|
||||
// ================== Связанные коллекции (общего назначения) ==================
|
||||
protected List<DeletedMessage> _deletedFor = new();
|
||||
public IReadOnlyCollection<DeletedMessage> DeletedFor => _deletedFor.AsReadOnly();
|
||||
|
||||
// ================== Инфраструктурный конструктор EF ==================
|
||||
protected Message() : base(Guid.Empty) { }
|
||||
|
||||
protected Message(
|
||||
Guid id,
|
||||
Guid chatId,
|
||||
Guid senderId,
|
||||
Guid? replyToId,
|
||||
Guid? forwardedFromId,
|
||||
DateTime createdAt,
|
||||
bool isImported) : base(id)
|
||||
{
|
||||
ChatId = chatId;
|
||||
SenderId = senderId;
|
||||
ReplyToId = replyToId;
|
||||
ForwardedFromId = forwardedFromId;
|
||||
CreatedAt = createdAt;
|
||||
|
||||
if (isImported) AddState(MessageState.IsImported);
|
||||
}
|
||||
|
||||
// ================== Управление Состоянием ==================
|
||||
public void AddState(MessageState state) => State |= state;
|
||||
public void RemoveState(MessageState state) => State &= ~state;
|
||||
public bool HasState(MessageState state) => (State & state) == state;
|
||||
|
||||
// ================== Общие операции ==================
|
||||
public virtual void Delete()
|
||||
{
|
||||
AddState(MessageState.IsDeleted);
|
||||
}
|
||||
|
||||
public void DeleteForUser(Guid userId)
|
||||
{
|
||||
if (!_deletedFor.Exists(x => x.UserId == userId))
|
||||
{
|
||||
_deletedFor.Add(new DeletedMessage(Id, userId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user