Skip to content

Commit 070c311

Browse files
committed
Fix DomainEvents
1 parent 5442dc1 commit 070c311

File tree

17 files changed

+187
-30
lines changed

17 files changed

+187
-30
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using KSFramework.KSMessaging.Abstraction;
2+
using Microsoft.Extensions.Logging;
3+
using Project.Domain.Aggregates.Blog.Events;
4+
5+
namespace Project.Application.Blog.EventHandlers;
6+
7+
public sealed class PostCreatedDomainEventHandler : INotificationHandler<PostCreatedDomainEvent>
8+
{
9+
private readonly ILogger<PostCreatedDomainEventHandler> _logger;
10+
11+
public PostCreatedDomainEventHandler(ILogger<PostCreatedDomainEventHandler> logger)
12+
{
13+
_logger = logger;
14+
}
15+
16+
public Task Handle(PostCreatedDomainEvent notification, CancellationToken cancellationToken)
17+
{
18+
_logger.LogInformation("Post created: {PostId} - {Title}", notification.PostId, notification.Title);
19+
20+
// Here you can add additional business logic like:
21+
// - Sending notifications
22+
// - Updating read models
23+
// - Triggering external systems
24+
25+
return Task.CompletedTask;
26+
}
27+
}

Samples/BlogApp/Project.Application/Project.Application.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net10.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
</PropertyGroup>

Samples/BlogApp/Project.ClientApp/Program.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@
1818

1919
app.UseAuthorization();
2020

21-
app.MapStaticAssets();
21+
app.UseStaticFiles();
2222

2323
app.MapControllerRoute(
2424
name: "default",
25-
pattern: "{controller=Home}/{action=Index}/{id?}")
26-
.WithStaticAssets();
25+
pattern: "{controller=Home}/{action=Index}/{id?}");
2726

2827

2928
app.Run();

Samples/BlogApp/Project.ClientApp/Project.ClientApp.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>net10.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
</PropertyGroup>

Samples/BlogApp/Project.Common/Project.Common.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net10.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
</PropertyGroup>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using KSFramework.KSDomain;
2+
3+
namespace Project.Domain.Aggregates.Blog.Events;
4+
5+
public sealed class PostCreatedDomainEvent : IDomainEvent
6+
{
7+
public PostCreatedDomainEvent(Guid postId, string title)
8+
{
9+
PostId = postId;
10+
Title = title;
11+
OccurredOn = DateTime.UtcNow;
12+
}
13+
14+
public Guid PostId { get; }
15+
public string Title { get; }
16+
public DateTime OccurredOn { get; }
17+
}

Samples/BlogApp/Project.Domain/Aggregates/Blog/Post.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using KSFramework.Utilities;
55
using Microsoft.EntityFrameworkCore;
66
using Microsoft.EntityFrameworkCore.Metadata.Builders;
7+
using Project.Domain.Aggregates.Blog.Events;
78

89
namespace Project.Domain.Aggregates.Blog;
910

@@ -44,6 +45,7 @@ public static Post Create(string title, string content)
4445
Id = Guid.NewGuid(),
4546
};
4647

48+
post.AddDomainEvent(new PostCreatedDomainEvent(post.Id, post.Title));
4749
return post;
4850
}
4951

Samples/BlogApp/Project.Domain/Project.Domain.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net10.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
</PropertyGroup>

Samples/BlogApp/Project.Infrastructure/Data/ApplicationDbContext.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,24 @@
22
using KSFramework.Utilities;
33
using Microsoft.EntityFrameworkCore;
44
using Project.Infrastructure.Outbox;
5+
using Microsoft.Extensions.DependencyInjection;
6+
using Project.Infrastructure.Services;
7+
using System.Linq;
58

69
namespace Project.Infrastructure.Data;
710

811
public class ApplicationDbContext : DbContext
912
{
10-
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
11-
:base(options)
13+
private readonly IDomainEventDispatcher _dispatcher;
14+
private readonly IServiceProvider _serviceProvider;
15+
16+
public ApplicationDbContext(
17+
DbContextOptions<ApplicationDbContext> options,
18+
IServiceProvider serviceProvider)
19+
: base(options)
1220
{
21+
_serviceProvider = serviceProvider;
22+
_dispatcher = _serviceProvider.GetRequiredService<IDomainEventDispatcher>();
1323
}
1424

1525
public DbSet<OutboxMessage> OutboxMessages { get; set; }
@@ -48,4 +58,26 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
4858

4959
#endregion
5060
}
61+
62+
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
63+
{
64+
var domainEvents = ChangeTracker.Entries<BaseEntity>()
65+
.SelectMany(x => x.Entity.DomainEvents)
66+
.ToList();
67+
68+
var result = await base.SaveChangesAsync(cancellationToken);
69+
70+
if (domainEvents.Any())
71+
{
72+
await _dispatcher.DispatchEventsAsync(domainEvents, cancellationToken);
73+
74+
// Clear domain events after dispatching
75+
foreach (var entry in ChangeTracker.Entries<BaseEntity>())
76+
{
77+
entry.Entity.ClearDomainEvents();
78+
}
79+
}
80+
81+
return result;
82+
}
5183
}

Samples/BlogApp/Project.Infrastructure/DependencyInjection.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using KSFramework.GenericRepository;
1+
using KSFramework.GenericRepository;
22
using Microsoft.AspNetCore.Builder;
33
using Microsoft.EntityFrameworkCore;
44
using Microsoft.Extensions.Configuration;
@@ -18,6 +18,8 @@ public static IServiceCollection RegisterInfrastructure(this IServiceCollection
1818
x =>
1919
x.MigrationsAssembly("Project.Infrastructure"));
2020
});
21+
22+
services.AddScoped<KSFramework.KSDomain.IDomainEventDispatcher, KSFramework.KSDomain.DomainEventDispatcher>();
2123
services.AddScoped<DbContext, ApplicationDbContext>();
2224
services.AddScoped<IUnitOfWork, UnitOfWork>();
2325
return services;

0 commit comments

Comments
 (0)