INotification
Namespace: RA.Utilities.Feature.Abstractions
The primary purpose of the INotification interface is to mark a class as a notification or event.
This is a key part of the CQRS and Mediator patterns for handling side effects and cross-cutting concerns in a clean, decoupled way.
While it might seem similar to IRequest, there is a fundamental difference in how they are handled:
IRequest(Command/Query): Represents a message that is sent to a single handler. It's a one-to-one communication pattern. You send a command and expect one handler to process it.INotification(Event): Represents a message that is published to multiple handlers (zero or more). It's a one-to-many, "publish-subscribe" communication pattern. You publish an event, and any part of your application that cares about that event can handle it without the publisher needing to know about the subscribers.
🛠️ How It's Used
In the context of your RA.Utilities solution, INotification enables you to trigger side effects after a primary operation completes.
For example, consider the CreateProductHandler.
After a product is successfully created, you might want to perform several follow-up actions:
- Invalidate the product cache.
- Send an email to the marketing team.
- Write an entry to an audit log.
- Instead of cluttering the
CreateProductHandlerwith all this logic, you would publish a notification:
Step 1: Define the Notification
First, you would define a class that implements INotification.
// In a new file: Features/Products/ProductCreatedNotification.cs
using RA.Utilities.Feature.Models; // Assuming INotification is aliased or available here
public record ProductCreatedNotification(int ProductId, string ProductName) : INotification;
Step 2: Publish the Notification
The CreateProductHandler would publish this notification after successfully saving the product. (This requires injecting a Publisher or Mediator service).
// In CreateProductHandler.cs
// ...
var productId = await _productRepository.AddAsync(newProduct);
// Publish an event for other parts of the system to react to
await _publisher.Publish(new ProductCreatedNotification(productId, newProduct.Name), cancellationToken);
return productId;
Step 3: Create Handlers for the Notification
Now, you can create multiple, small, focused handlers that each subscribe to ProductCreatedNotification.
// In Features/Caching/CacheInvalidationHandler.cs
public class CacheInvalidationHandler : INotificationHandler<ProductCreatedNotification>
{
public Task Handle(ProductCreatedNotification notification, CancellationToken cancellationToken)
{
// Invalidate product cache logic here...
return Task.CompletedTask;
}
}
// In Features/Auditing/AuditLogHandler.cs
public class AuditLogHandler : INotificationHandler<ProductCreatedNotification>
{
public Task Handle(ProductCreatedNotification notification, CancellationToken cancellationToken)
{
// Write to audit log logic here...
return Task.CompletedTask;
}
}
🧠 Summary
In summary, INotification is the key to implementing a robust, decoupled eventing system within your Vertical Slice Architecture,
allowing features to remain self-contained while still communicating with other parts of the application.