VOOZH about

URL: https://www.nuget.org/packages/DKNet.EfCore.Events/

⇱ NuGet Gallery | DKNet.EfCore.Events 10.0.27




👁 Image
DKNet.EfCore.Events 10.0.27

dotnet add package DKNet.EfCore.Events --version 10.0.27
 
 
NuGet\Install-Package DKNet.EfCore.Events -Version 10.0.27
 
 
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DKNet.EfCore.Events" Version="10.0.27" />
 
 
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DKNet.EfCore.Events" Version="10.0.27" />
 
Directory.Packages.props
<PackageReference Include="DKNet.EfCore.Events" />
 
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DKNet.EfCore.Events --version 10.0.27
 
 
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: DKNet.EfCore.Events, 10.0.27"
 
 
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DKNet.EfCore.Events@10.0.27
 
 
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DKNet.EfCore.Events&version=10.0.27
 
Install as a Cake Addin
#tool nuget:?package=DKNet.EfCore.Events&version=10.0.27
 
Install as a Cake Tool
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

DKNet.EfCore.Events

👁 NuGet
👁 NuGet Downloads
👁 .NET

Enhanced Entity Framework Core event-based functionality for implementing domain-driven design (DDD) patterns. This library provides centralized event management, automatic event publishing during EF Core operations, and seamless integration with domain entities.

Features

  • Domain Event Management: Queue and publish domain events from entities
  • Automatic Event Publishing: Events fired automatically during EF Core SaveChanges
  • Event Publisher Abstraction: Central hub for event routing and handling
  • EF Core Hooks Integration: Pre and post-save event triggers
  • Custom Event Handlers: Flexible event handling with dependency injection
  • Entity Event Tracking: Track and manage events at the entity level
  • Exception Handling: Robust error handling for event processing
  • Performance Optimized: Efficient event queuing and batch processing

Supported Frameworks

  • .NET 9.0+
  • Entity Framework Core 9.0+

Installation

Install via NuGet Package Manager:

dotnet add package DKNet.EfCore.Events

Or via Package Manager Console:

Install-Package DKNet.EfCore.Events

Quick Start

Setup Event Publisher

using DKNet.EfCore.Events.Handlers;
using Microsoft.Extensions.DependencyInjection;

// Register event publisher implementation
services.AddEventPublisher<AppDbContext, EventPublisher>();

// Or use your custom implementation
public class CustomEventPublisher : IEventPublisher
{
 public async Task PublishAsync(object eventItem, CancellationToken cancellationToken = default)
 {
 // Custom event publishing logic
 await Task.CompletedTask;
 }
}

services.AddEventPublisher<AppDbContext, CustomEventPublisher>();

Domain Entity with Events

using DKNet.EfCore.Abstractions.Entities;

public class Product : Entity<Guid>
{
 public Product(string name, decimal price, string createdBy) 
 : base(Guid.NewGuid(), createdBy)
 {
 Name = name;
 Price = price;
 
 // Add domain event
 AddEvent(new ProductCreatedEvent(Id, name, price));
 }

 public string Name { get; private set; }
 public decimal Price { get; private set; }
 
 public void UpdatePrice(decimal newPrice, string updatedBy)
 {
 var oldPrice = Price;
 Price = newPrice;
 SetUpdatedBy(updatedBy);
 
 // Add domain event for price change
 AddEvent(new ProductPriceChangedEvent(Id, oldPrice, newPrice));
 }
}

// Domain events
public record ProductCreatedEvent(Guid ProductId, string Name, decimal Price);
public record ProductPriceChangedEvent(Guid ProductId, decimal OldPrice, decimal NewPrice);

Event Handlers

using DKNet.EfCore.Events.Handlers;

public class ProductCreatedHandler : INotificationHandler<ProductCreatedEvent>
{
 private readonly ILogger<ProductCreatedHandler> _logger;
 private readonly IEmailService _emailService;

 public ProductCreatedHandler(ILogger<ProductCreatedHandler> logger, IEmailService emailService)
 {
 _logger = logger;
 _emailService = emailService;
 }

 public async Task Handle(ProductCreatedEvent notification, CancellationToken cancellationToken)
 {
 _logger.LogInformation("Product created: {ProductId} - {Name} (${Price})", 
 notification.ProductId, notification.Name, notification.Price);
 
 // Send notification email
 await _emailService.SendProductCreatedNotificationAsync(notification, cancellationToken);
 }
}

public class ProductPriceChangedHandler : INotificationHandler<ProductPriceChangedEvent>
{
 private readonly IInventoryService _inventoryService;

 public ProductPriceChangedHandler(IInventoryService inventoryService)
 {
 _inventoryService = inventoryService;
 }

 public async Task Handle(ProductPriceChangedEvent notification, CancellationToken cancellationToken)
 {
 // Update inventory records
 await _inventoryService.UpdatePriceAsync(notification.ProductId, notification.NewPrice, cancellationToken);
 }
}

Configuration

DbContext Setup

Events are automatically published during SaveChanges when the event hook is registered:

public class AppDbContext : DbContext
{
 public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

 public DbSet<Product> Products { get; set; }
 public DbSet<Order> Orders { get; set; }

 // Event publishing happens automatically via EventHook
}

Event Handler Registration

// Register event handlers
services.AddScoped<INotificationHandler<ProductCreatedEvent>, ProductCreatedHandler>();
services.AddScoped<INotificationHandler<ProductPriceChangedEvent>, ProductPriceChangedHandler>();

// Or use MediatR for automatic discovery
services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(ProductCreatedHandler).Assembly));

API Reference

Core Interfaces

  • IEventPublisher - Central event publishing abstraction
  • IEventEntity - Interface for entities that can raise domain events (from DKNet.EfCore.Abstractions)
  • EntityEventItem - Wrapper for entity events with metadata

Event Management

  • AddEvent(object) - Queue domain event on entity
  • ClearEvents() - Clear all queued events
  • GetEvents() - Retrieve all queued events

Setup Extensions

  • AddEventPublisher<TDbContext, TImplementation>() - Register event publisher with EF Core hooks

Advanced Usage

Custom Event Publisher

public class MediatREventPublisher : IEventPublisher
{
 private readonly IMediator _mediator;
 private readonly ILogger<MediatREventPublisher> _logger;

 public MediatREventPublisher(IMediator mediator, ILogger<MediatREventPublisher> logger)
 {
 _mediator = mediator;
 _logger = logger;
 }

 public async Task PublishAsync(object eventItem, CancellationToken cancellationToken = default)
 {
 try
 {
 _logger.LogDebug("Publishing event: {EventType}", eventItem.GetType().Name);
 
 if (eventItem is INotification notification)
 {
 await _mediator.Publish(notification, cancellationToken);
 }
 else
 {
 _logger.LogWarning("Event {EventType} does not implement INotification", eventItem.GetType().Name);
 }
 }
 catch (Exception ex)
 {
 _logger.LogError(ex, "Failed to publish event: {EventType}", eventItem.GetType().Name);
 throw new EventException($"Failed to publish event of type {eventItem.GetType().Name}", ex);
 }
 }
}

Complex Domain Event Scenarios

public class Order : AggregateRoot
{
 private readonly List<OrderItem> _items = [];

 public Order(Guid customerId, string createdBy) : base(createdBy)
 {
 CustomerId = customerId;
 Status = OrderStatus.Pending;
 
 AddEvent(new OrderCreatedEvent(Id, customerId));
 }

 public Guid CustomerId { get; private set; }
 public OrderStatus Status { get; private set; }
 public IReadOnlyList<OrderItem> Items => _items.AsReadOnly();
 public decimal TotalAmount => _items.Sum(i => i.TotalPrice);

 public void AddItem(Guid productId, int quantity, decimal unitPrice)
 {
 var item = new OrderItem(productId, quantity, unitPrice);
 _items.Add(item);
 
 AddEvent(new OrderItemAddedEvent(Id, productId, quantity, unitPrice));
 }

 public void Complete(string updatedBy)
 {
 if (Status != OrderStatus.Pending)
 throw new InvalidOperationException("Only pending orders can be completed");

 Status = OrderStatus.Completed;
 SetUpdatedBy(updatedBy);
 
 AddEvent(new OrderCompletedEvent(Id, CustomerId, TotalAmount, Items.Count));
 }

 public void Cancel(string reason, string updatedBy)
 {
 if (Status == OrderStatus.Completed)
 throw new InvalidOperationException("Completed orders cannot be cancelled");

 Status = OrderStatus.Cancelled;
 SetUpdatedBy(updatedBy);
 
 AddEvent(new OrderCancelledEvent(Id, reason));
 }
}

// Domain events
public record OrderCreatedEvent(Guid OrderId, Guid CustomerId);
public record OrderItemAddedEvent(Guid OrderId, Guid ProductId, int Quantity, decimal UnitPrice);
public record OrderCompletedEvent(Guid OrderId, Guid CustomerId, decimal TotalAmount, int ItemCount);
public record OrderCancelledEvent(Guid OrderId, string Reason);

Event Handler with Side Effects

public class OrderCompletedHandler : INotificationHandler<OrderCompletedEvent>
{
 private readonly IInventoryService _inventoryService;
 private readonly IPaymentService _paymentService;
 private readonly INotificationService _notificationService;
 private readonly ILogger<OrderCompletedHandler> _logger;

 public OrderCompletedHandler(
 IInventoryService inventoryService,
 IPaymentService paymentService,
 INotificationService notificationService,
 ILogger<OrderCompletedHandler> logger)
 {
 _inventoryService = inventoryService;
 _paymentService = paymentService;
 _notificationService = notificationService;
 _logger = logger;
 }

 public async Task Handle(OrderCompletedEvent notification, CancellationToken cancellationToken)
 {
 try
 {
 // Update inventory
 await _inventoryService.ReserveItemsAsync(notification.OrderId, cancellationToken);
 
 // Process payment
 await _paymentService.ProcessPaymentAsync(notification.OrderId, notification.TotalAmount, cancellationToken);
 
 // Send confirmation
 await _notificationService.SendOrderConfirmationAsync(notification.CustomerId, notification.OrderId, cancellationToken);
 
 _logger.LogInformation("Order {OrderId} completed successfully. Total: ${TotalAmount}, Items: {ItemCount}",
 notification.OrderId, notification.TotalAmount, notification.ItemCount);
 }
 catch (Exception ex)
 {
 _logger.LogError(ex, "Failed to process order completion for {OrderId}", notification.OrderId);
 
 // Could add compensating actions or raise error events
 throw new EventException($"Failed to process order completion for {notification.OrderId}", ex);
 }
 }
}

Event Lifecycle

  1. Event Creation: Domain events are added to entities during business operations
  2. Event Queuing: Events are stored in entity's event collection until SaveChanges
  3. Event Publishing: Events are automatically published during EF Core SaveChanges via EventHook
  4. Event Handling: Registered event handlers process the events asynchronously
  5. Event Cleanup: Successfully processed events are cleared from entities

Error Handling

public class RobustEventPublisher : IEventPublisher
{
 private readonly IMediator _mediator;
 private readonly ILogger<RobustEventPublisher> _logger;

 public async Task PublishAsync(object eventItem, CancellationToken cancellationToken = default)
 {
 var maxRetries = 3;
 var retryDelay = TimeSpan.FromMilliseconds(100);

 for (int attempt = 1; attempt <= maxRetries; attempt++)
 {
 try
 {
 await _mediator.Publish((INotification)eventItem, cancellationToken);
 return;
 }
 catch (Exception ex) when (attempt < maxRetries)
 {
 _logger.LogWarning(ex, "Event publishing failed on attempt {Attempt} for {EventType}. Retrying...", 
 attempt, eventItem.GetType().Name);
 
 await Task.Delay(retryDelay * attempt, cancellationToken);
 }
 catch (Exception ex)
 {
 _logger.LogError(ex, "Event publishing failed after {MaxRetries} attempts for {EventType}", 
 maxRetries, eventItem.GetType().Name);
 throw new EventException($"Failed to publish event after {maxRetries} attempts", ex);
 }
 }
 }
}

Performance Considerations

  • Batch Processing: Events are published in batches during SaveChanges
  • Async Handlers: All event handlers should be async for non-blocking execution
  • Memory Management: Events are cleared after successful publishing
  • Transaction Scope: Events are published within the same transaction as data changes

Best Practices

  • Single Responsibility: Keep event handlers focused on one concern
  • Idempotency: Design event handlers to be idempotent
  • Error Isolation: Don't let event handler failures affect the main transaction
  • Event Versioning: Plan for event schema evolution
  • Testing: Test event handlers independently from entities

Contributing

See the main for guidelines on how to contribute to this project.

License

This project is licensed under the .

Related Packages

  • - Core abstractions including IEventEntity
  • - EF Core functionality extensions
  • - EF Core lifecycle hooks (used internally)
  • - Alternative CQRS event handling

Part of the DKNet Framework - A comprehensive .NET framework for building modern, scalable applications.

Product Versions Compatible and additional computed target framework versions.
.NET net10.0 net10.0 is compatible.  net10.0-android net10.0-android was computed.  net10.0-browser net10.0-browser was computed.  net10.0-ios net10.0-ios was computed.  net10.0-maccatalyst net10.0-maccatalyst was computed.  net10.0-macos net10.0-macos was computed.  net10.0-tvos net10.0-tvos was computed.  net10.0-windows net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on DKNet.EfCore.Events:

Package Downloads
DKNet.SlimBus.Extensions

DKNet is an enterprise-grade .NET library collection focused on advanced EF Core extensions, dynamic predicate building, and the Specification pattern. It provides production-ready tools for building robust, type-safe, and testable data access layers, including dynamic LINQ support, LinqKit integration. Designed for modern cloud-native applications, DKNet enforces strict code quality, async best practices, and full documentation for all public APIs. Enterprise-grade .NET library suite for modern application development, featuring advanced EF Core extensions (dynamic predicates, specifications, LinqKit), robust Domain-Driven Design (DDD) patterns, and domain event support. DKNet empowers scalable, maintainable, and testable solutions with type-safe validation, async/await, XML documentation, and high code quality standards. Ideal for cloud-native, microservices, and enterprise architectures.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.0.27 150 5/22/2026
10.0.26 105 5/19/2026
10.0.25 427 3/27/2026
10.0.24 128 3/27/2026
10.0.23 125 3/27/2026
10.0.22 117 3/26/2026
10.0.21 186 3/17/2026
10.0.20 139 2/2/2026
10.0.19 289 1/21/2026
10.0.18 128 1/21/2026
10.0.17 147 1/19/2026
10.0.16 129 1/18/2026
10.0.15 134 1/18/2026
10.0.14 137 1/18/2026
10.0.13 128 1/17/2026
10.0.12 132 1/17/2026
10.0.11 136 1/17/2026
10.0.10 127 1/17/2026
10.0.9 139 1/16/2026
10.0.8 140 1/16/2026
Loading failed