Create Command
The EntityCreateCommand<TCreateModel, TReadModel> represents a command to create a new entity using the specified create model. This command follows the CQRS (Command Query Responsibility Segregation) pattern and returns a read model representing the created entity.
Overview
The create command is a fundamental part of the Arbiter framework's CRUD operations. It inherits from EntityModelCommand<TCreateModel, TReadModel> which provides automatic security context, audit tracking, and JSON serialization support.
public record EntityCreateCommand<TCreateModel, TReadModel>
: EntityModelCommand<TCreateModel, TReadModel>, ICacheExpire
Key Features
- Security Context: Built-in
ClaimsPrincipalsupport for authentication and authorization - Audit Tracking: Automatic creation metadata tracking including
Created,CreatedBy,Updated, andUpdatedByfields - Cache Integration: Implements
ICacheExpirefor automatic cache invalidation - Validation: Integrated with validation pipeline behaviors
- Mapping: Uses Mapper for converting between create models and entities
- Tenant Support: Optional multi-tenant support through
IHaveTenant<TKey>interface
Type Parameters
| Parameter | Description |
|---|---|
TCreateModel |
The type of the create model containing the data for the new entity |
TReadModel |
The type of the read model returned as the result of the command |
Constructor Parameters
| Parameter | Type | Description |
|---|---|---|
principal |
ClaimsPrincipal? |
The user's security context. Used for audit tracking and authorization |
model |
TCreateModel |
The create model containing the data for the new entity |
Automatic Metadata Tracking
When an entity implements tracking interfaces, the command automatically populates metadata:
ITrackCreated: SetsCreatedtimestamp andCreatedByuser identifierITrackUpdated: SetsUpdatedtimestamp andUpdatedByuser identifier
Handler Implementations
The Arbiter framework provides built-in handlers for different data access patterns:
Entity Framework Handler
EntityCreateCommandHandler<TContext, TEntity, TKey, TCreateModel, TReadModel>
MongoDB Handler
EntityCreateCommandHandler<TRepository, TEntity, TKey, TCreateModel, TReadModel>
Service Registration
Register create command support using the provided extension methods:
Entity Framework
services.AddEntityCommands<MyDbContext, Product, int, ProductReadModel, ProductCreateModel, ProductUpdateModel>();
// Or register create command individually
services.AddEntityCreateCommand<MyDbContext, Product, int, ProductCreateModel, ProductReadModel>();
MongoDB
services.AddEntityCommands<IProductRepository, Product, int, ProductReadModel, ProductCreateModel, ProductUpdateModel>();
// Or register create command individually
services.AddEntityCreateCommand<IProductRepository, Product, int, ProductCreateModel, ProductReadModel>();
Model Mapping with IMapper
The create command relies on IMapper<TSource, TDestination> to convert between different model types during the entity creation process. The framework uses two key mapping operations:
CreateModel to Entity Mapping
The command handler uses IMapper<TCreateModel, TEntity> to convert the incoming create model into an entity that can be persisted to the database:
var entity = Mapper.Map<TCreateModel, TEntity>(request.Model);
Entity to ReadModel Mapping
After the entity is created and saved, IMapper<TEntity, TReadModel> converts the persisted entity into a read model for the response:
return Mapper.Map<TEntity, TReadModel>(entity);
Pipeline Behaviors
The create command automatically includes several pipeline behaviors that execute in the pipeline:
Tenant Security:
TenantDefaultCommandBehaviorandTenantAuthenticateCommandBehavior(if entity implementsIHaveTenant<TKey>)TenantDefaultCommandBehavior: Automatically sets the tenant ID from the current user's claims when not explicitly providedTenantAuthenticateCommandBehavior: Validates that the user has access to the specified tenant and ensures tenant isolation
Validation:
ValidateEntityModelCommandBehavior- Performs model validation using data annotations or FluentValidation rules defined on the create model
- Throws validation exceptions if the model is invalid, which are automatically converted to HTTP 400 responses in web applications
Notifications:
EntityChangeNotificationBehavior- Publishes domain events or notifications when entities are created, allowing other parts of the system to react to changes
- Useful for implementing event-driven architectures and cross-cutting concerns like logging or cache invalidation
Usage Examples
Basic Usage
var createModel = new ProductCreateModel
{
Name = "New Product",
Description = "A description of the new product",
Price = 19.99m
};
var principal = new ClaimsPrincipal(new ClaimsIdentity([new(ClaimTypes.Name, "JohnDoe")]));
var command = new EntityCreateCommand<ProductCreateModel, ProductReadModel>(principal, createModel);
var result = await mediator.Send(command);
Console.WriteLine($"Created product: {result?.Name}");
In ASP.NET Core Controller
[HttpPost]
public async Task<ProductReadModel?> CreateProduct([FromBody] ProductCreateModel createModel)
{
var command = new EntityCreateCommand<ProductCreateModel, ProductReadModel>(User, createModel);
return await mediator.Send(command);
}
In Minimal API Endpoint
app.MapPost("/products", async (
[FromServices] IMediator mediator,
[FromBody] ProductCreateModel createModel,
ClaimsPrincipal user) =>
{
var command = new EntityCreateCommand<ProductCreateModel, ProductReadModel>(user, createModel);
var result = await mediator.Send(command);
return Results.Ok(result);
});
Return Values
- Success: Returns the
TReadModelrepresenting the created entity - Exception: Throws appropriate exceptions for validation or data access errors
Error Handling
The command handlers include built-in error handling and will throw appropriate exceptions:
ArgumentNullException: When the model parameter is nullDomainException: For business rule violations- Database exceptions: For data access errors
Best Practices
- Model Validation: Implement data annotations or FluentValidation on your create models
- Mapping Configuration: Configure Mapper for
TCreateModeltoTEntitymapping - Security: Always pass the current user's
ClaimsPrincipalfor proper audit tracking - Null Handling: The command constructor validates that the model is not null
- Cache Tags: The framework automatically manages cache invalidation based on entity types
- Authorization: Implement appropriate authorization checks in your application layer