文章目錄
- 項目地址
- 一、KeyCloak
- 二、OutBox Pattern
- 2.1 配置Common模塊的OutBox
- 1. OutboxMessage
- 2. 數據庫配置OutboxMessageConfiguration
- 3. 創建Save前的EF攔截器
- 4. 創建Quartz后臺任務
- 5. 配置后臺任務
- 6. 注冊服務
- 2.2 創建OutBox的消費者
- 1. 自定義IDomainEventHandler
- 2. 定義抽象類DomainEventHandler
- 3. 更改之前的EventHandler
- 4. 注冊DomainEventHandler
- 5. 創建DomainEventHandlersFactory
- 6. 使用DomainEventHandlersFactory
- 7. 冪等性包裝器事件處理器
- 2.3 Inbox Pattern
項目地址
- 教程作者:
- 教程地址:
- 代碼倉庫地址:
- 所用到的框架和插件:
dbt
airflow
一、KeyCloak
王教員 029-033
二、OutBox Pattern
王 38-40
2.1 配置Common模塊的OutBox
1. OutboxMessage
- 定義Outbox message
namespace Evently.Common.Infrastructure.Outbox;public sealed class OutboxMessage
{//消息idpublic Guid Id { get; init; }//消息類型 例如UserRegisteredEventpublic string Type { get; init; }//消息內容 Json格式public string Content { get; init; }//消息發生時間public DateTime OccurredOnUtc { get; init; }//消息處理時間,可為空,表示沒有被消費public DateTime? ProcessedOnUtc { get; init; }//消息錯誤信息public string? Error { get; init; }
}
2. 數據庫配置OutboxMessageConfiguration
- 創建OutBoxMessage表需要用到的數據庫配置
namespace Evently.Common.Infrastructure.Outbox;
public sealed class OutboxMessageConfiguration : IEntityTypeConfiguration<OutboxMessage>
{public void Configure(EntityTypeBuilder<OutboxMessage> builder){builder.ToTable("outbox_messages");builder.HasKey(o => o.Id);builder.Property(o => o.Content).HasMaxLength(2000).HasColumnType("jsonb");}
}
- 在User模塊里需要用到消息服務,所以需要在User模塊的schema里添加表的migration
namespace Evently.Modules.Users.Infrastructure.Database;
public sealed class UsersDbContext(DbContextOptions<UsersDbContext> options) : DbContext(options), IUnitOfWork
{internal DbSet<User> Users { get; set; }protected override void OnModelCreating(ModelBuilder modelBuilder){modelBuilder.HasDefaultSchema(Schemas.Users);modelBuilder.ApplyConfiguration(new OutboxMessageConfiguration());modelBuilder.ApplyConfiguration(new UserConfiguration());modelBuilder.ApplyConfiguration(new RoleConfiguration());modelBuilder.ApplyConfiguration(new PermissionConfiguration());}
}
- 在User模塊下,執行遷移,生成outbox_messages表
3. 創建Save前的EF攔截器
- 之前我們使用的攔截器是在數據庫save之后在進行事件的發布,現在我們直接在save之前,自動將領域事件轉換為OutBoxMessage并存入數據庫
public sealed class InsertOutboxMessagesInterceptor : SaveCha