.NET Основные разработки реальных боевых действий (Урок 30: области проведения мероприятий: бизнес для повышения сплоченности и достижения расцепления модуля) - Study Notes

30 | полевые мероприятия: для повышения сплоченности бизнеса, достижения расцепления модуля

Мы уровень абстракции определяет интерфейс в области полевых событий и обработки событий поля

IDomainEvent

namespace GeekTime.Domain
{
    public interface IDomainEvent : INotification
    {
    }
}

Это пустой интерфейс, который лишь помечается конкретный объект, является ли событие поля, INotification является пустым интерфейсом, который является интерфейс MediatR структура используется для достижения с доставкой событий

namespace MediatR
{
    public interface INotification
    {
    }
}

Вслед за IDomainEventHandler

namespace GeekTime.Domain
{
    public interface IDomainEventHandler<TDomainEvent> : INotificationHandler<TDomainEvent> 
        where TDomainEvent : IDomainEvent
    {
        //这里我们使用了INotificationHandler的Handle方法来作为处理方法的定义
        //Task Handle(TDomainEvent domainEvent, CancellationToken cancellationToken);
    }
}

Этот интерфейс также наследует один и тот же интерфейс IDomainEventHandler, который имеет общий параметр TDomainEvent, это TDomainEvent ограничение должно быть IDomainEvent, то есть обработчик обрабатывает только IDomainEvent, как в Сенат

На самом деле, этот метод был определен в INotificationHandler Хорошо, так что нет никакой необходимости переназначения, просто чтобы сказать вам, что это определение того, что это было похоже

Адресные области кодов событий в Entity

private List<IDomainEvent> _domainEvents;
public IReadOnlyCollection<IDomainEvent> DomainEvents => _domainEvents?.AsReadOnly();

public void AddDomainEvent(IDomainEvent eventItem)
{
    _domainEvents = _domainEvents ?? new List<IDomainEvent>();
    _domainEvents.Add(eventItem);
}

public void RemoveDomainEvent(IDomainEvent eventItem)
{
    _domainEvents?.Remove(eventItem);
}

public void ClearDomainEvents()
{
    _domainEvents?.Clear();
}

Полевые события приходят в сущности хранения имущества, он должен быть список, потому что больше чем одна вещь может произойти в середине рабочего органа процесса, поле должно быть прочитано в коде события внешней твердотельной модели, так воздействия на ReadOnly Коллекция

Там также предусмотрено несколько способов: Добавить событие поле, удалить поле события, очистить поле события

Эти методы вызываются внутри модели домена

Заказ можно посмотреть на определенные ранее

public Order(string userId, string userName, int itemCount, Address address)
{
    this.UserId = userId;
    this.UserName = userName;
    this.Address = address;
    this.ItemCount = itemCount;

    this.AddDomainEvent(new OrderCreatedDomainEvent(this));
}

public void ChangeAddress(Address address)
{
    this.Address = address;
    //this.AddDomainEvent(new OrderAddressChangedDomainEvent(this));
}

Когда мы строим новый Орден, когда, на самом деле, здесь вы можете определить событие называется OrderCreatedDomainEvent, это поле событие в его параметр конструктора является порядок, когда мы называем конструктор заказа, на самом деле, наше поведение, создать новый орден, так что здесь добавить AddDomainEvent события

Точно так же пример ChangeAddress был назван, здесь мы действительно можем определить событие OrderAddressChangedDomainEvent поля, как этот ребенок из

Вы можете увидеть поле строительства и добавлять события должны быть завершены в рамках метода модели домена, и не должны быть вне кода, чтобы создать вызов, потому что эти события происходят внутри модели домена

Тогда посмотрите на определение OrderCreatedDomainEvent

namespace GeekTime.Domain.Events
{
    public class OrderCreatedDomainEvent : IDomainEvent
    {
        public Order Order { get; private set; }
        public OrderCreatedDomainEvent(Order order)
        {
            this.Order = order;
        }
    }
}

Как мы имеем дело с нашими полевыми событиями, полевые мероприятия на лечение должны быть определены на уровне приложения

namespace GeekTime.API.Application.DomainEventHandlers
{
    public class OrderCreatedDomainEventHandler : IDomainEventHandler<OrderCreatedDomainEvent>
    {
        ICapPublisher _capPublisher;
        public OrderCreatedDomainEventHandler(ICapPublisher capPublisher)
        {
            _capPublisher = capPublisher;
        }

        public async Task Handle(OrderCreatedDomainEvent notification, CancellationToken cancellationToken)
        {
            await _capPublisher.PublishAsync("OrderCreated", new OrderCreatedIntegrationEvent(notification.Order.Id));
        }
    }
}

Он наследует IDomainEventHandler, этот интерфейс области интерфейса, упомянутые выше обработчиков событий, его общие типы параметров OrderCreatedDomainEvent событие должно быть обработано

Для простоты ради представления, логика здесь является то, что при создании нового заказа, мы публикуем событие EventBus, это событие называется OrderCreated

Определим CreateOrderCommand в CreateOrder OrderController

[HttpPost]
public async Task<long> CreateOrder([FromBody]CreateOrderCommand cmd)
{
    return await _mediator.Send(cmd, HttpContext.RequestAborted);
}

CreateOrderCommand

namespace GeekTime.API.Application.Commands
{
    public class CreateOrderCommand : IRequest<long>
    {

        //ublic CreateOrderCommand() { }
        public CreateOrderCommand(int itemCount)
        {
            ItemCount = itemCount;
        }

        public long ItemCount { get; private set; }
    }
}

CreateOrderCommandHandler

public async Task<long> Handle(CreateOrderCommand request, CancellationToken cancellationToken)
{

    var address = new Address("wen san lu", "hangzhou", "310000");
    var order = new Order("xiaohong1999", "xiaohong", 25, address);

    _orderRepository.Add(order);
    await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
    return order.Id;
}

Мы создали CreateOrderCommandHandler внутри ордена, а затем сохранить в хранилище, называемом UnitOfWork из SaveEntitiesAsync

Запустите программу, оформленную непосредственно, позвоните в наш метод, мы можем видеть, что мы впервые вошли в создание системы обработки заказов (CreateOrderCommandHandler), затем в Publish код (MediatorExtension) полевые события выпустили, когда память для хранения завершена, в OrderCreatedDomainEventHandler , то есть после того, как мы закончим создание нашей модели предметной области и сохранить его, наш обработчик события поля срабатывают только

Объясняя достичь UnitOfWork до (EFContext), наша SaveEntitiesAsync есть только одна строка кода SaveChangesAsync, чтобы добавить строку кода, отправляется код события поле DispatchDomainEventsAsync

public async Task<bool> SaveEntitiesAsync(CancellationToken cancellationToken = default)
{
    var result = await base.SaveChangesAsync(cancellationToken);
    //await _mediator.DispatchDomainEventsAsync(this);
    return true;
}

Это MediatorExtension видели DispatchDomainEventsAsync

namespace GeekTime.Infrastructure.Core.Extensions
{
    static class MediatorExtension
    {
        public static async Task DispatchDomainEventsAsync(this IMediator mediator, DbContext ctx)
        {
            var domainEntities = ctx.ChangeTracker
                .Entries<Entity>()
                .Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any());

            var domainEvents = domainEntities
                .SelectMany(x => x.Entity.DomainEvents)
                .ToList();

            domainEntities.ToList()
                .ForEach(entity => entity.Entity.ClearDomainEvents());

            foreach (var domainEvent in domainEvents)
                await mediator.Publish(domainEvent);
        }
    }
}

Мы можем видеть, что мы посылаем событие поля на самом деле такой процесс: мы хотим, чтобы сохранить текущие EntityContext идти внутри отслеживать нашу сущность, а затем получить на трек от объекта сущности нашего текущего события, событие существует, если , поставить его, то объект очищенного события, а затем эти события разослали один за другим через пО промежуточного слой, и процесс, чтобы найти соответствующий Handler

события Определение полей на самом деле очень просто, создать каталог событий в модели предметной области, то поле события, определенные здесь, полевые события должны наследовать IDomainEvent, поле процессор события определяются в DomainEventHandler, прикладной уровень в этой директории Здесь мы можем определить обработчик для каждого события

Подводя итог

Создание модели в области события: Мы не выходить за пределы модели доменной структуры события, а затем перешли к модели предметной области, поскольку все поле событий инициируются бизнес-логикой поля, а не что работа модели снаружи триггера

Другое для полевых мероприятий следует определять конкретную области класса обработчика событий, как мы только что продемонстрировали, в определенном каталоге, определяются для каждого класса обработки событий

Еще в одной и той же сделки, чтобы иметь дело с нашими полевыми событиями, на самом деле, мы можем также выбрать дело в отдельной сделке, которая, если время, необходимое для рассмотрения событий в различных областях дела внутри, нам нужно рассмотреть последовательность вопрос, рассмотрит проблему потери сообщения об ошибке среднего

Creative Commons License

Эта работа Creative Commons Attribution - Некоммерческая - ShareAlike 4.0 Международное Лицензионное соглашение по лицензированию.

Добро пожаловать на переиздание, использование, перепечатывать, но не забудьте сохранить статью за подписью Чжэн Цзымином (содержащие ссылки: http://www.cnblogs.com/MingsonZheng/ ), не должен использоваться в коммерческих целях, не забудьте опубликовать ту же работу на основе модификации лицензионной бумаги ,

Если у вас есть какие-либо вопросы, пожалуйста, свяжитесь со мной ([email protected]).

рекомендация

отwww.cnblogs.com/MingsonZheng/p/12556333.html