Skip to main content

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:

  1. Invalidate the product cache.
  2. Send an email to the marketing team.
  3. Write an entry to an audit log.
  4. Instead of cluttering the CreateProductHandler with 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.Abstractions;

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 HandleAsync(ProductCreatedNotification notification, CancellationToken cancellationToken)
{
// Invalidate product cache logic here...
return Task.CompletedTask;
}
}

// In Features/Auditing/AuditLogHandler.cs
public class AuditLogHandler : INotificationHandler<ProductCreatedNotification>
{
public Task HandleAsync(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.