Skip to content

Solution projects structure

César Demicheli edited this page Oct 19, 2022 · 6 revisions

Solution structure

Monaco's solution structure is composed as follows:

image

  • nuget.config: The Nuget configuration for the current solution. More package sources can be configured in it.
  • Common: this folder contains all the libraries that provide abstractions for each of the layers and that are cross-solution. Most of these projects generate a Nuget package by default, meaning that they can be separated into a different repository in order to share the same libraries in multiple solutions if required.
    • Tests/Monaco.Template.Common.Domain.Tests: Unit tests for the Common.Domain library classes.
    • Monaco.Template.Common.Api: Abstractions for the Web API application (Swagger, Middleware, CORS, Auth, etc)
    • Monaco.Template.Common.Api.Application: mainly for MediatR's extensions that simplify returning values on the Web API application.
    • Monaco.Template.Common.ApiGateway: YARP-based API Gateway implementation.
    • Monaco.Template.Common.Application: Abstractions for the Application library.
    • Monaco.Template.Common.BlobStorage: client library for working with the Azure Blob Storage.
    • Monaco.Template.Common.Domain: Base classes and interfaces for the Domain library.
    • Monaco.Template.Common.Infrastructure: Base classes and interfaces for the Infrastructure library (DbContext, EntityTypeConfiguration, Auditing, extensions, etc).
    • Monaco.Template.Common.Messaging.Messages: messaging library for placing integration events classes if MassTransit is included.
    • Monaco.Template.Common.Serilog: extensions and enrichers for Serilog.
    • Monaco.Template.Common.Tests: AutoFixture's fixtures setup and configuration and other common tests elements.
  • Keycloak: A Keycloak's configuration file for setting up a new Realm.
  • Tests: this folder contains the test projects for the actual implementation projects.
    • Monaco.Template.Application.Tests: tests for the Monaco.Template.Application project.
    • Monaco.Template.Domain.Tests: tests for the Monaco.Template.Domain project.
  • Monaco.Template.Api: ASP.NET WebAPI project.
  • Monaco.Template.Application: Application business library that exposes all the Commands and Queries as interface to interact from the executing assembly and execute the different features the Application exposes. It may also contain any service classes used for interacting with external services.
  • Monaco.Template.Application.Infrastructure: Infrastructure configuration for the Application, such us EF Core DbContext and ORM-DB mapping configurations.
  • Monaco.Template.Application.Infrastructure.Migrations: EF Core migrations assembly. Useful to decouple the code generated for migrations to improve compilation times when not needed.
  • Monaco.Template.Domain: Domain entities and model diagram.

Projects structure

Monaco.Template.Common.Api

image

This project contains attributes, middleware and extensions that are intended to be used on the Api project.

  • JwtMapClaimsAttribute: Attribute for marking controller's actions to apply the JwtClaimsMapperMiddleware.
  • AuthExtensions: Extensions for simplifying the configuration of JwtBearer authentication, configuring authorization policies and such.
  • ScopeClaimsTransformation: claim transformation for converting a scope claim from a space-separated string into multiple individual scope claims for better interpretation.
  • CorsExtensions: Extensions for simplifying the CORS configuration.
  • MiddlewareExtensions: extensions for applying different middlewares.
  • JwtClaimsMapperMiddleware: middleware for populating ClaimsPrincipal with JWT claims if present in request, despite of whether the authentication is enabled or not on the API. Useful for using behind an API Gateway and having authentication disabled but the claims are still required for business logic.
  • SerilogContextEnricherMiddleware: middleware for enriching Serilog's LogContext with ClaimsPrincipal claims.
  • AuthorizeCheckOperationFilter: Swagger's operation filter for applying correct responses to protected endpoints.
  • ConfigureSwaggerExtensions: Swagger extensions for simplifying its configuration on the API project.
  • SwaggerDefaultValues: Swagger's operation filter for setting up some default values that are not correctly handled by the library.

Monaco.Template.Common.Api.Application

image

This project contains extensions for simplifying Commands and Queries responses from MediatR for returning the correct results from the API project.

  • ResponseType: helper enum.
  • MediatorExtensions: extensions for MediatR's Mediator to return adequate responses to the API from the Commands and Queries.

Monaco.Template.Common.ApiGateway

image

This project is an API Gateway implementation of YARP. The reverseProxy.json file will contain all the YARP configuration to not pollute the appsettings.json.

Monaco.Template.Common.Application

image

This project contains base and generic classes for the MediatR's Commands, Queries and Behaviors to use on the Application project, as well as other extensions to simplify other operations.

  • BehaviorExtensions: Extensions for registering the PreCommandProcessorBehavior classes in the DI.
  • PreCommandProcessorBehavior: generic classes for defining MediatR's PipelineBehaviors to automate validation during the execution of Commands.
  • ICommandResult: Interfaces for the commands results.
  • CommandBase: base generic classes for implementing Commands as part of Monaco's recommended command implementation.
  • CommandResult: generic result for the commands inheriting from the CommandBase classes.
  • QueryExtensions: extensions for simplifying the execution of generic queries.
  • QueryBase: generic base class for implementing a Query that accepts any number of parameters and returns any type of result.
  • QueryByIdBase: generic base class for implementing a Query that requires an Id parameter and returns any type of result.
  • QueryByKeyBase: generic base class for implementing a Query that requires a lookup field of any type and returns any type of value.
  • QueryPagedBase: generic base class for implementing a Query that accepts any number of parameters and returns a page of results, picking up the Offset and Limit params from the initial parameters and providing default values if not found).
  • INonInjectable: interface for marking validators that should not be picked and injected into the DI container.
  • ValidatorExtensions: extensions for simplifying validations and checks with FluentValidation.

Monaco.Template.Common.BlobStorage

image

This project is a convenience library for dealing with file against Azure Blob Storage.

Monaco.Template.Common.Domain

image

This project contains the base classes to declare entities, enumerations or domain events. It's meant to be used as a common library to be reused in multiple projects and will generate a Nuget by default.

  • Entity: it's the base class for all the entities to inherit from. It provides the basic functionality to include Domain Events and overrides to allow to compare entities instances between them correctly.
  • Enumeration: a subtype of entity that allows to implement enumeration classes to identify multiple different values from an entity (aka: smart enums)
  • Page: a generic class that represents a page of elements with pagination metadata.
  • DomainEvent: a base class to implement domain events that can be consumed for collateral effects.

Monaco.Template.Common.Infrastructure

image

This project contains base classes and extensions for implementing the Application's Infrastructure library.

  • AuditEntry: class to track changes to the entities entries on EF Core.
  • AuditLog: helper class for simplifying the enriching of Serilog's Log with the auditing information.
  • IUnitOfWork: Interface for the unit of work.
  • FilterExtensions: extensions for applying generic filtering to LINQ queries.
  • MediatorExtension: extensions for simplifying the dispatching of event domains via MediatR.
  • OperationsExtensions: extensions for simplifying generic retrieval and of entities and their existence on the DB.
  • PagingExtensions: extensions for simplifying the handling and conversion of results to paged result sets.
  • SelectMapExtensions: extensions for simplifying the filtering and mapping of LINQ queries.
  • SortingExtensions: extensions for applying generic sorting to LINQ queries.
  • BaseDbContext: base DbContext to inherit from that will include several features like automatic discovery of EntityTypeConfigurations, dispatch of domain events, auditing, etc.
  • EntityTypeBuilderExtensions: extensions for simplifying configuration of entities with EntityTypeBuilder.
  • EntityTypeConfigurationBase: base class for inheriting in EntityTypeConfigurations meant for entities that require seed. It will prevent reading the seed if it's not in Development environment and with the debugger attached.

Monaco.Template.Common.Messaging.Messages

This project is a placeholder for containing messaging classes in case Monaco is instructed to generate a solution with support for MassTransit.

Monaco.Template.Common.Serilog

image

This project contains additional converters, enrichers and extensions for Serilog.

  • AuditEventTelemetryConverter: Serilog converter for creating events for DB transactions auditing.
  • OperationTelemetryConverter: Serilog converter for improved tracking of operations along with userId and userName.
  • OperationIdEnricher: Serilog enricher for including operationId and parentId properties in the log event.
  • SerilogExtensions: extensions for simplify enricher registration.

Monaco.Template.Common.Tests

image

This project will contain common dependencies for the test projects.

  • Factories/Entities: this directory is meant to contain factories and extensions for registering AutoFixture's fixtures for the different domain entities that might required to be tested.
  • AnonymousDataAttribute: attribute derived from AutoDataAttribute for injecting data on xUnit's Theories with registered fixtures.
  • FixtureExtensions: extensions for configuring AutoFixture.

Monaco.Template.Application.Tests

image

This project will contain all the unit tests for the Application's command handlers, their corresponding validators and also queries handlers.

Monaco.Template.Domain.Tests

image

This project will contain all the unit tests for the Domain entities

Monaco.Template.Api

image

This project is the ASP.NET Core API of the solution and the startup project by default.

  • Auth/Scopes: listing of all the scopes available for the API for the scope-based authorization. Available only when Authentication/Authorization is enabled.
  • Controllers: this directory is meant to contain all the controllers of the REST API. There will be a few controllers as part of the initial samples.
  • DTOs: this directory will contain the DTOs required as the endpoints interfaces (mainly only the ones required as inputs).
  • DTOs/Extensions: this directory will contain the DTOs extensions for performing mappings between the API's DTOs and the Commands/Queries from the Application.
  • appsettings.json/appsettings.Development.json: the configuration files.
  • Program: the main program file and startup configuration.

Monaco.Template.Application

image

This project is the Application library that is meant to contain all the application logic of the solution. It's should not have any reference to ASP.NET nor any other kind of dependency of the application used as part of the presentation layer of the solution. Some features and services are already included by default as part of the sample use cases implemented. They can be removed/replaced/reused as needed.

  • ApplicationOptions: class for mapping configuration options for the Application.
  • ServiceCollectionExtensions: extensions for configuring Application's dependency injection.
  • DTOs: this directory will contain all the DTOs used for inputs/outputs of the Application's commands/queries.
  • DTOs/Extensions: this directory will contain all the extensions for mapping DTOs, Commands, Queries and Entities between each other.
  • Features: this directory will contain all the different Application's features, grouped by entity, and then grouped by the type of action: Command or Query. Commands will also include the Validators directory where the corresponding commands' validators will be placed. Commands and Queries folders will include both the commands or queries and also their corresponding handlers.
  • Services: this directory will contain any service meant for cross-feature concerns.

Monaco.Template.Application.Infrastructure

image

This project will contain the infrastructure components of the Application (DbContext, EntityTypeConfigurations, seeds, etc). It's meant to be part of the Application layer but as a separate assembly for reducing compilation times.

  • AppDbContext: the implementation of the BaseDbContext for this Application.
  • EntityConfigurations: this directory will contain the EntityTypeConfigurations for each of the entities from the Domain.
  • EntityConfigurations/Seeds: this directory will contain the seeds for the entities that needs to be seeded.

Monaco.Template.Application.Infrastructure.Migrations

image

This project will contain the EF Core migrations corresponding for the changes applied to the model in the Domain. It's meant to be part of the Application layer but as a separate assembly for reducing compilation times.

Monaco.Template.Domain

image

This project will contain the domain entities that will be used for the business logic and mapped against the DB. Monaco encourages the use of a rich domain model in order to better encapsulate its logic and keep the Application logic at a minimum. Some entities are already included by default as part of the sample use cases implemented. They can be removed/replaced/reused as needed.

Clone this wiki locally