Skip to content

Latest commit

 

History

History
119 lines (92 loc) · 3.22 KB

README.md

File metadata and controls

119 lines (92 loc) · 3.22 KB

中 | EN

DomainEventBus

Example:

Install-Package MASA.Contrib.DDD.Domain
Install-Package MASA.Contrib.DDD.Domain.Repository.EF

Install-Package MASA.Contrib.Dispatcher.Events

Install-Package MASA.Contrib.Dispatcher.IntegrationEvents.Dapr
Install-Package MASA.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF
Install-Package MASA.Contrib.Data.UoW.EF
  1. Add DomainEventBus
builder.Services
.AddDomainEventBus(options =>
{
    options.UseEventBus()//Use in-process events
        .UseUoW<CustomDbContext>(dbOptions => dbOptions.UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=idientity"))
        .UseDaprEventBus<IntegrationEventLogService>()///Use cross-process events
        .UseEventLog<CustomDbContext>()
        .UseRepository<CustomDbContext>();//Use the EF version of Repository to achieve
})
  1. Add DomainCommand
public class RegisterUserDomainCommand : DomainCommand
{
    public string User { get; set; } = default!;

    public string Password { get; set; } = default!;

    public string PhoneNumber { get; set; } = default!;
}

DomainQuery refers to Query in CQRS

  1. Add Handler (in process)
public class UserHandler
{
    [EventHandler]
    public Task RegisterUserHandlerAsync(RegisterUserDomainCommand command)
    {
        //TODO Registered user business
    }
}
  1. Send DomainCommand
IDomainEventBus eventBus;//Get IDomainEventBus through DI
await eventBus.PublishAsync(new RegisterUserDomainCommand());//Send DomainCommand
  1. Define domain events
public class RegisterUserSucceededIntegrationEvent : IntegrationDomainEvent
{
    public override string Topic { get; set; } = nameof(RegisterUserSucceededIntegrationEvent);

    public string Account { get; set; } = default!;
}

public class RegisterUserSucceededEvent : DomainEvent
{
    public string Account { get; set; } = default!;
}
  1. Define domain services
public class UserDomainService : DomainService
{
    public UserDomainService(IDomainEventBus eventBus) : base(eventBus)
    {
    }

    public async Task RegisterSucceededAsync(string account)
    {
        await EventBus.Enqueue(new RegisterUserSucceededIntegrationEvent() { Account = account });
        await EventBus.Enqueue(new RegisterUserSucceededEvent() { Account = account });
        await EventBus.PublishQueueAsync();
    }
}

DomainEvent (in-process) and IntegrationDomainEvent (cross-process) can be inherited as needed

If you only need to send a domain event, you can directly use EventBus.PublishQueueAsync(new RegisterUserSucceededEvent())

If you want to send in a unified way, you can send it through EventBus.Enqueue() and finally call EventBus.PublishQueueAsync()

Tip:

  1. The use of DomainEventBus must require the implementation of IEventBus and IIntegrationEventBus and IUnitOfWork
  2. EventBus only supports in-process scheduling, cross-process scheduling is not supported, and the sending order is consistent with the enqueue order, but the actual execution order is unknown
  1. Cross-process event subscription
[Topic("pubsub", nameof(RegisterUserSucceededIntegrationEvent))]
public async Task RegisterUserSucceededHandlerAsync(RegisterUserSucceededIntegrationEvent @event)
{
    //todo
}