.NET Núcleo desenvolvimento combate real (Lição 30: áreas Evento: negócios para melhorar a coesão e conseguir a dissociação módulo) - Notas de Estudo

30 | eventos de campo: para melhorar a coesão do negócio, conseguir a dissociação módulo

Nós camada de abstração define a interface na área de eventos de campo e manipulação de eventos de campo

IDomainEvent

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

Esta é uma interface vazia, que apenas marcados se um determinado objeto é um evento de campo, INotification é uma interface vazia, que é um quadro MediatR interface é usada para alcançar com a entrega de eventos

namespace MediatR
{
    public interface INotification
    {
    }
}

Seguido por IDomainEventHandler

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

Esta interface também herda a mesma interface IDomainEventHandler, que tem um parâmetro genérico é TDomainEvent, essa restrição TDomainEvent deve ser IDomainEvent, ou seja alças manipulador única IDomainEvent como para o Senado

Na verdade, este método foi definido no INotificationHandler Ok, por isso não há necessidade de redefinir, apenas para dizer-lhe que é a definição de como era

áreas de endereço de códigos de evento na entidade

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();
}

Os eventos de campo que vêm em uma entidade de armazenamento de propriedade, deve ser uma lista, porque mais do que uma coisa pode acontecer no meio de uma entidade operacional processo, o campo deve ser lido no exterior código de evento do modelo sólido, de modo a exposição a um ReadOnly a Coleção

Há também é fornecido algumas maneiras: Adicionar um evento de campo, remover os eventos de campo, limpar os eventos de campo

Estes métodos são invocados no interior do modelo de domínio

Fim pode olhar para o previamente definido

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));
}

Quando nós construir uma nova ordem, quando, na verdade, aqui você pode definir um evento chamado de OrderCreatedDomainEvent, este evento de campo em seu parâmetro de construtor é uma Ordem, quando chamamos o construtor Ordem, na verdade, o nosso comportamento é, criar uma nova ordem, por isso aqui adicionar um AddDomainEvent evento

Da mesma forma o exemplo ChangeAddress sido chamado, aqui podemos realmente definir um evento de campo OrderAddressChangedDomainEvent como esta fora criança

Você pode ver o domínio da construção e adicionar eventos devem ser concluídas dentro do método de modelo de domínio, e não deve estar fora do código para criar a chamada, porque esses eventos estão acontecendo dentro do modelo de domínio

Então olha para a definição de OrderCreatedDomainEvent

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

Como lidamos com os nossos eventos de campo, eventos de campo para receber o tratamento deve ser definido na camada de aplicação

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));
        }
    }
}

Ele herda a IDomainEventHandler, esta interface é as áreas de interface mencionados acima manipuladores de eventos, seus tipos de parâmetros genéricos OrderCreatedDomainEvent o evento é para ser processado

Por causa da simplicidade da apresentação, a lógica aqui é que quando nós criamos uma nova ordem, publicamos um evento para EventBus, este evento é chamado OrderCreated

Nós definimos um CreateOrderCommand na 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;
}

Criamos CreateOrderCommandHandler dentro de uma Ordem, e depois salvar no armazém, chamado UnitOfWork de SaveEntitiesAsync

Inicie o programa, executado diretamente, ligue para o nosso método, podemos ver que entrou pela primeira vez em criar um sistema de processamento de pedidos (CreateOrderCommandHandler), então no código Publicar (MediatorExtension) eventos de campo liberada, quando a memória de armazenamento for concluída, no OrderCreatedDomainEventHandler , ou seja, depois que terminar de criar o nosso modelo de domínio e salvá-lo, o nosso manipulador de eventos de campo só é acionado

Ao explicar para alcançar UnitOfWork antes (EFContext), o nosso SaveEntitiesAsync há apenas uma linha de código é SaveChangesAsync, aqui para adicionar uma linha de código, é enviado código de evento campo DispatchDomainEventsAsync

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

Esta é MediatorExtension visto 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);
        }
    }
}

Nós podemos ver que nós enviar um evento de campo é realmente tal processo a: queremos salvar as EntityContext atuais ir para dentro rastrear nossa entidade, então, fazer a trilha da entidade objeto para nosso atual Evento, existe evento se , colocá-lo para fora, então a entidade Evento desmarcada, e em seguida, estes eventos enviou um por um através do middleware, eo processo de encontrar o manipulador correspondente

eventos definição de campo, na verdade, muito simples, basta criar um diretório Eventos no modelo de domínio, em seguida, os eventos de campo são definidos aqui, os eventos de campo precisam IDomainEvent herdar, eventos de campo processador são definidos no DomainEventHandler, a camada de aplicação neste diretório aqui, podemos definir o nosso manipulador para cada evento

para resumir

Criar um modelo no domínio do evento: Nós não ir para fora da estrutura de modelo de domínio do evento, e depois passou para o modelo de domínio, porque toda a área de eventos é desencadeada pela lógica de negócios do campo, ao invés de que o funcionamento do modelo fora do gatilho

O outro é para eventos de campo deve definir áreas específicas de classe manipulador de eventos, como acabamos de demonstrar, em um diretório específico, definido para cada classe de processamento de eventos

Outra é na mesma transação que lidar com os nossos eventos de campo, de fato, podemos também optar por lidar com em uma transação separada, que, se o tempo necessário para lidar com eventos em diferentes áreas de negócios dentro, é preciso considerar a consistência pergunta, considere os problemas de perda de mensagem de erro médio

Creative Commons License

Este trabalho é Creative Commons Attribution - Contrato de Licença ShareAlike 4.0 International - Não comercial para o licenciamento.

Bem-vindo a reimpressão, uso, repost, mas não se esqueça de manter o artigo assinado por Zheng Ziming (contendo links: http://www.cnblogs.com/MingsonZheng/ ), não devem ser utilizados para fins comerciais, não se esqueça de publicar o mesmo trabalho com base na modificação licença de papel .

Se você tiver alguma dúvida, entre em contato comigo ([email protected]).

Acho que você gosta

Origin www.cnblogs.com/MingsonZheng/p/12556333.html
Recomendado
Clasificación