Разделенные модели в чистой архитектуре с вызовом событий предметной областиC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Разделенные модели в чистой архитектуре с вызовом событий предметной области

Сообщение Anonymous »

На уровне домена у меня есть простой интерфейс для реализации событий домена.

Код: Выделить всё

public interface IDomainEvent
{
[NotMapped]
IReadOnlyCollection DomainEvents { get; }
void AddDomainEvent(DomainEvent notificationEvent);
void RemoveDomainEvent(DomainEvent notificationEvent);
void ClearDomainEvents();
}
Затем я определил их в своем классе Entity

Код: Выделить всё

public abstract class Entity : IDomainEvent
{

private readonly List _domainEvents = new();
[NotMapped]
public IReadOnlyCollection DomainEvents => _domainEvents.AsReadOnly();
public virtual void AddDomainEvent(DomainEvent newEvent)
{
_domainEvents.Add(newEvent);
}
public virtual void RemoveDomainEvent(DomainEvent eventItem)
{
_domainEvents.Remove(eventItem);
}
public virtual void ClearDomainEvents()
{
_domainEvents.Clear();
}

}
Это помогает мне, когда я сохраняю модель домена в базе данных с моим шаблоном исходящих сообщений, который реализуется перехватчиками EF Core. Я нахожу их и сохраняю в одной транзакции.

Код: Выделить всё

public class DomainEventOutboxInterceptor : SaveChangesInterceptor
{
public override ValueTask SavingChangesAsync(DbContextEventData eventData, InterceptionResult result,
CancellationToken cancellationToken = new())
{
if (eventData.Context != null)
{
InsertOutboxMessages(eventData.Context);
}
return base.SavingChangesAsync(eventData, result, cancellationToken);
}
private static void InsertOutboxMessages(DbContext dbContext)
{
var domainEvents = dbContext.ChangeTracker.Entries()
.Select(e => e.Entity)
.Where(e => e.DomainEvents.Count != 0)
.SelectMany(e =>
{
var domainEvents = e.DomainEvents.ToList();
e.ClearDomainEvents();
return domainEvents;
})
.ToList();
var outboxMessages = domainEvents.Select(domainEvent => new OutboxMessage
{
Id = Guid.NewGuid(),
Name = domainEvent.GetType().Name,
Content = JsonSerializer.Serialize(domainEvent, domainEvent.GetType()),
CreatedOn = DateTimeOffset.Now,
IsProcessed = false,
ProcessedOn = null,
}).ToList();
if (outboxMessages.Count > 0)
dbContext.Set().AddRange(outboxMessages);
}
}
Поэтому, если я использую модель домена в своем репозитории и контексте БД, все работает хорошо, и я также могу сохранять события домена, но моя проблема в некоторых сценариях: модель домена и модель базы данных различаются. и мне приходится создавать модели базы данных отдельно и сопоставлять их на уровне приложения. Если я создаю эквивалентную модель БД, то там нет события предметной области, и во время сохранения изменений я никогда не смогу их сохранить. это означает, что я всегда должен работать со своими моделями предметной области как с моделями баз данных. когда я проверял репозитории с чистой архитектурой в Github, все они использовались следующим образом. (модели предметной области как модели базы данных)

Код: Выделить всё

public class Post : Entity
{
public Title Title { get; private set; }
public Content Content { get; private set; }
public DateTime CreatedAt { get; private set; }
public Author Author { get; private set; }

private readonly List _comments = new();
public IReadOnlyList Comments => _comments.AsReadOnly();
}

public class PostModel
{
public Guid Id { get; set; }
public string Title { get; set; } = string.Empty;
public string Author { get; set; } = string.Empty;
public string Content { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public ICollection Comments { get; set; } = new List();
}

Код: Выделить всё

PostModel
не имеет идентификатора IDomainEvent, и пока я сохраняю шаблон исходящих сообщений, он не работает.
Как я могу разделить модели домена и базы данных, используя при этом преимущества создания событий домена и исходящего ящика шаблон?
Или вообще, неправильно ли всегда использовать модели предметной области в качестве моделей БД? если нет, то как вы справляетесь с различными конструкциями баз данных?

Подробнее здесь: https://stackoverflow.com/questions/792 ... nt-raising
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»