Layers : Application
The Application layer templates generate the complete CQRS implementation for each entity within a bounded context. The generator produces commands (Create, Edit, Delete) and queries (GetList, GetDetails, GetEdit, GetDelete) with their handlers, proxies, requests, responses, validators, repository interfaces, service contracts, domain event handlers, application errors, and localization resources — all driven by the entity definitions configured in the Scaffolder.net UI.
Project File
The {{Solution.Name}}.Application.{{BoundedContext.Name}}.csproj file defines the application project with references to the Domain project (same bounded context) and the Shared.Application project, providing access to the mediator, CQRS abstractions, and domain entities.
Assembly Reference
The {{Solution.Name}}Application{{BoundedContext.Name}}AssemblyReference class is an internal sealed marker class used to reference the application assembly for reflection-based service registration and dependency injection scanning.
Dependency Injection
The ServiceCollectionExtension class provides the AddApplicationServices method that registers the mediator, command services, query services, command handlers, query handlers, domain event handlers, and the domain event publisher by scanning the application assembly. It also conditionally generates an AddApplicationServiceProxies method when a Blazor WebAssembly or Minimal API presentation is enabled, registering handler proxies instead of local handlers for remote execution via HTTP.
Global Usings
The GlobalUsings.cs file is generated with global using directives for all entity command and query namespaces within the bounded context, including commands (Create, Delete, Edit), repositories, errors, queries (GetDelete, GetDetails, GetEdit, GetList), query repositories, and resources. It also includes global usings for domain entity and domain service namespaces, and shared application abstractions.
Commands : Create
- Create{{Entity.NameSingular}}Command : An internal sealed record implementing
ICommand<Create{{Entity.NameSingular}}CommandResponse>, wrapping the command request. - Create{{Entity.NameSingular}}CommandHandler : An internal sealed handler that validates the request, calls the entity's
CreateAsyncfactory method via the domain service, adds the entity to the command repository, saves changes through the Unit of Work, and returns the created entity's data as a response. - Create{{Entity.NameSingular}}CommandHandlerProxy : An internal sealed proxy that sends the create request as an HTTP POST to the Web API, deserializes the response, and maps problem details to errors on failure.
- Create{{Entity.NameSingular}}CommandRequest : A public sealed record containing all entity properties (with Id if not auto-generated), generated by the
ApplicationGenerator.GetFullPropertiesmethod. - Create{{Entity.NameSingular}}CommandRequestValidator : An internal sealed FluentValidation validator that validates the request's Id (if not auto-generated) and all properties with the same rules as the domain entity validator.
- Create{{Entity.NameSingular}}CommandResponse : A public sealed record containing the entity's Id and all property values, returned after a successful creation.
Commands : Delete
- Delete{{Entity.NameSingular}}Command : An internal sealed record implementing
ICommand<Delete{{Entity.NameSingular}}CommandResponse>, wrapping the command request. - Delete{{Entity.NameSingular}}CommandHandler : An internal sealed handler that retrieves the entity by Id, returns a
NotFounderror if not found, calls the entity'sDeletemethod, removes it from the command repository, saves changes, and returns the deleted entity's data. - Delete{{Entity.NameSingular}}CommandHandlerProxy : An internal sealed proxy that sends the delete request as an HTTP DELETE to the Web API, maps a 404 response to a
NotFounderror, and deserializes the response on success. - Delete{{Entity.NameSingular}}CommandRequest : A public sealed record containing only the entity's Id.
- Delete{{Entity.NameSingular}}CommandResponse : A public sealed record containing the entity's Id and all property values, returned after a successful deletion.
Commands : Edit
- Edit{{Entity.NameSingular}}Command : An internal sealed record implementing
ICommand<Edit{{Entity.NameSingular}}CommandResponse>, wrapping the command request. - Edit{{Entity.NameSingular}}CommandHandler : An internal sealed handler that validates the request, retrieves the entity by Id (returns
NotFoundif not found), calls the entity'sEditAsyncmethod, updates the command repository, saves changes, and returns the edited entity's data. - Edit{{Entity.NameSingular}}CommandHandlerProxy : An internal sealed proxy that sends the edit request as an HTTP PUT to the Web API, maps 404 to
NotFoundand 400/422 to problem details errors, and deserializes the response on success. - Edit{{Entity.NameSingular}}CommandRequest : A public sealed record containing the entity's Id and all property values (with DateTime properties made nullable for edit context), generated by the
ApplicationGenerator.GetInlinePropertiesTypeAndNameandGetFullPropertiesAssignationmethods. - Edit{{Entity.NameSingular}}CommandRequestValidator : An internal sealed FluentValidation validator that validates the request's Id and all properties with the same rules as the domain entity validator.
- Edit{{Entity.NameSingular}}CommandResponse : A public sealed record containing the entity's Id and all property values, returned after a successful edition.
Commands : Domain Event Handlers
GenerateDomainEvents option is enabled for an entity, the generator creates three internal sealed event handlers implementing IDomainEventHandler<T> :
- {{Entity.NameSingular}}CreatedDomainEventHandler : Logs the created domain event with the entity's Id and all property values.
- {{Entity.NameSingular}}DeletedDomainEventHandler : Logs the deleted domain event with the entity's Id and all property values.
- {{Entity.NameSingular}}EditedDomainEventHandler : Logs the edited domain event with the entity's Id and all property values.
Commands : Repository Interface
The I{{Entity.NameSingular}}CommandRepository interface extends ICommandRepository and defines write-side data access methods : Add, Update, Remove, and GetEntityAsync for retrieving an entity by its Id.
Commands : Services
- I{{Entity.NameSingular}}CommandService : An interface extending
ICommandServicethat definesCreate{{Entity.NameSingular}}Async,Edit{{Entity.NameSingular}}Async, andDelete{{Entity.NameSingular}}Asyncmethods, each accepting the corresponding command request and returning aResult<TResponse>. - {{Entity.NameSingular}}CommandService : A sealed implementation that injects the
IMediatorand dispatches each method as a command through the mediator pipeline.
Application Errors
The {{Entity.NameSingular}}ApplicationError static class contains a nested sealed NotFound error class that accepts a string localizer and the entity's Id, producing a localized "not found" error message with ErrorTypeEnum.NotFound.
Queries : GetDelete
- GetDelete{{Entity.NameSingular}}Query : An internal sealed record implementing
IQuery<Delete{{Entity.NameSingular}}CommandRequest>, wrapping the query request. - GetDelete{{Entity.NameSingular}}QueryHandler : An internal sealed handler that retrieves the delete command request (entity data for confirmation) from the query repository, returning a
NotFounderror if the entity does not exist. - GetDelete{{Entity.NameSingular}}QueryHandlerProxy : An internal sealed proxy that sends an HTTP GET to the Web API's
/{{Entity.NamePlural}}/{{Id}}/GetDeleteendpoint, mapping 404 to aNotFounderror. - GetDelete{{Entity.NameSingular}}QueryRequest : A public sealed record containing only the entity's Id.
Queries : GetDetails
- Get{{Entity.NameSingular}}DetailsQuery : An internal sealed record implementing
IQuery<Get{{Entity.NameSingular}}DetailsQueryResponse>, wrapping the query request. - Get{{Entity.NameSingular}}DetailsQueryHandler : An internal sealed handler that retrieves the details response from the query repository, returning a
NotFounderror if the entity does not exist. - Get{{Entity.NameSingular}}DetailsQueryHandlerProxy : An internal sealed proxy that sends an HTTP GET to the Web API's
/{{Entity.NamePlural}}/{{Id}}endpoint, mapping 404 to aNotFounderror. - Get{{Entity.NameSingular}}DetailsQueryRequest : A public sealed record containing only the entity's Id.
- Get{{Entity.NameSingular}}DetailsQueryResponse : A public sealed record containing the entity's Id and all property values, returned for the details view.
Queries : GetEdit
- GetEdit{{Entity.NameSingular}}Query : An internal sealed record implementing
IQuery<Edit{{Entity.NameSingular}}CommandRequest>, wrapping the query request. - GetEdit{{Entity.NameSingular}}QueryHandler : An internal sealed handler that retrieves the edit command request (entity data for the edit form) from the query repository, returning a
NotFounderror if the entity does not exist. - GetEdit{{Entity.NameSingular}}QueryHandlerProxy : An internal sealed proxy that sends an HTTP GET to the Web API's
/{{Entity.NamePlural}}/{{Id}}/GetEditendpoint, mapping 404 to aNotFounderror. - GetEdit{{Entity.NameSingular}}QueryRequest : A public sealed record containing only the entity's Id.
Queries : GetList
- Get{{Entity.NameSingular}}ListQuery : An internal sealed record implementing
IQuery<IReadOnlyCollection<Get{{Entity.NameSingular}}ListQueryResponse>>, wrapping the query request. - Get{{Entity.NameSingular}}ListQueryHandler : An internal sealed handler that retrieves the list of entities from the query repository and returns them as a read-only collection of responses.
- Get{{Entity.NameSingular}}ListQueryHandlerProxy : An internal sealed proxy that sends an HTTP GET to the Web API's
/{{Entity.NamePlural}}endpoint, mapping non-success status codes to problem details or internal errors, and returning an empty collection if the response is null. - Get{{Entity.NameSingular}}ListQueryRequest : A public sealed record with no parameters, used as the query input for the list operation.
- Get{{Entity.NameSingular}}ListQueryResponse : A public sealed record containing the entity's Id and all property values, returned for each item in the list view.
Queries : Repository Interface
The I{{Entity.NameSingular}}QueryRepository interface extends IQueryRepository and defines read-side data access methods : GetListAsync, GetDetailsAsync, GetEditAsync, and GetDeleteAsync, each accepting the corresponding query request and a cancellation token.
Queries : Services
- I{{Entity.NameSingular}}QueryService : An interface extending
IQueryServicethat definesGet{{Entity.NameSingular}}ListAsync,Get{{Entity.NameSingular}}DetailsAsync,GetEdit{{Entity.NameSingular}}Async, andGetDelete{{Entity.NameSingular}}Asyncmethods, each accepting the corresponding query request and returning aResult<TResponse>. - {{Entity.NameSingular}}QueryService : A sealed implementation that injects the
IMediatorand dispatches each method as a query through the mediator pipeline.
Resources
{{Solution.Name}}Application{{BoundedContext.Name}}Resource class and its associated .resx file provide localized strings for the application layer. The generator populates the .resx with :
- Not found error messages (e.g.,
{{Entity.NameSingular}}ApplicationError.NotFound) with parameterized Id values. - Command request property display names (e.g.,
Create{{Entity.NameSingular}}CommandRequest.{{PropertyName}},Edit{{Entity.NameSingular}}CommandRequest.{{PropertyName}}) using humanized names for FluentValidation display name resolution.