Skip to content

Suite Services

The Suite Framework's main purpose is to provide everything you need for you to focus on building your business and application logic.

Suite Services are building blocks for the Suite 3.0. They follow the microservices pattern and implement a single autonomous functionality.

For better understanding of the concepts used in this section please make sure you have read the Fundamentals first.

Suite's application modules are built following the concepts and guidelines of Clean Architecture and Domain-Driven Design.

It is important to keep a clean design of our services, and to follow common practices between them in order to be able to keep them up to date by possibly different teams.

Projects Structure

Services are composed of multiple projects in order to provide a clear set of contracts and multi-db provider support. We can decompose a service, by following clean architecture, into an Application, Domain and Infrastructure Layer. Where the Infrastructure usually means persistence.

Please do read the Naming Conventions for detailed information on naming your service, its projects and namespaces.

Application Layer

The Application Layer contains logic specifically designed for the application purposes. Application and Application.Contracts projects holds the application specific logic and abstractions respectively.

The Application.Contracts includes interfaces which extend from IAppService and it's corresponding DTO; these are used for Dynamic HTTP Client generation.

Note

The recommendation for defining DTOs is to use C# Records. There's no need to use interfaces.

Application.Contracts also includes AMQP Message Contracts, which are required by services that consume our service's events, or for services that produce our events.

The Application Layer is also responsible of converting Domain Entities to DTOs and vice versa. Basically, the Application Layer exposes an application use case, which receives DTOs and returns DTOs.

It never receives nor return Domain Entities, since these are implementation details of the Domain Layer; and besides, they are usually not serializable. DTO and Domain entity boundary

See Application Layer section for more details.

Domain Layer

Domain project contains business entities, aggregate roots, repositories and domain service objects.

We do not recommend creating a separate project to hold domain entities unless it's required.

Inside the Domain layer, avoid using attribute decorators. When using any Suite Module, or third party library, prefer conventions over configurations. Inversion of control is key.

See Domain Layer section for more details.

Infrastructure Layer

Infrastructure Layer is usually split into multiple projects depending on the functionality or external service they integrate with.

A clear example of Infrastructure is the Persistence project, where common symbols like class mappings, data seeding, and other non DB provider symbols are held.

The Persistence.SqlServer includes symbols specific for running against a particular DB Engine, and the packages or dependencies required for doing so.

The way to toggle between which provider is chosen can be done by depending on all of your Persistence.{DbProvider} projects in your Application project. Then, we can select a provider using the Entity Framework Module ProviderKey configuration.

Tip

In order to produce smaller deliverables, Applications are encouraged to use the External Module Discovery in order to depend on these their DB Provider modules.

Support for other DB Providers will be added in the form of Persistence.Oracle, implementing the Module Provider Pattern.

See Infrastructure Layer section for more details.

Recommendations

  • Isolate as much as possible from implementation details
  • Use DDD concepts as much as possible (Entities, AggregateRoots, etc)
  • Avoid business logic in application Layer