The UI should be completely separated from any business logic or API code. The UI should only contain logic related to presentation; no calculations should be performed.
The UI should have a separate source code repository and a separate .NET (or other) solution. One benefit to this separation is that the UI and service can be independently deployed and scaled.
The UI should not use the same models as used by the service/business logic to represent the database (data models); client models and mapping should be used as a layer of abstraction.
The UI should consume RESTful web services for all business logic, processing, and data access activities.
All business logic, processing, and data access should occur in the API layer.
At a high level the API should be broken into the following components:
In most instances the head of the application will be an API project that provides request/response for RESTful APIs. It is also common to use a console (command line) project as the head of the application especially in the case of batch processing. The head of the application can also be replaced to create a constantly running windows service. Other Azure options including replacing the head with an Azure Function or a Web Job.
Domain Services (or just services) is where logic and processing occur for the application.
All error handling should occur in the services layer.
The services layer loosely correlates to the “BLL” (Business Logic Layer) used by legacy systems.
Domain models represent the actual data schema as accessed by the ORM.
Domain models should only be used internally by the application.
After any processing of data models by the service layer, any results should be mapped to client models and returned as part of the response.
Client models also include the Request and Response objects.
All data access should implement the repositories pattern.
A separate repository project should be used for each ORM + Data Source (DB) combination.
The repositories layer loosely correlates to the “DAL” (Data Access Layer) used by legacy systems.