Components

BlackSlope utilizes both internal code and some third-party packages to handle specific responsibilities. Each of these packages makes up a Component and can define any necessary settings specific to its responsibilities in the appsettings.json file.

The following are descriptions of various components contained within BlackSlope. Implementations of these components are based on convenient, well-tested third-party packages, but implementations can be swapped out for your own preferred code as well.

Fluent Validation

Validation of requests happens in the Operations layer. To do this, BlackSlope implements Fluent Validation.

Swagger

For API documentation, BlackSlope utilizes Swagger. Keep in mind that any necessary settings for Swagger can be set in the appsettings.json file.

AutoMapper

The three different layers within BlackSlope use different data models for different purposes: Operations primarily uses View Models (formatted for endpoint consumption), Services use Domain Models (internal application representation), and Repositories use DTOs (storage representation).

Translating data between the three different model types for each layer is necessary: In the Operations layer, View Models need to be transformed into Domain Models for the Services to use. Similarly in the Services layer, Domain Models need to be transformed into DTOs for the Repositories to use. To simplify this process, BlackSlope utilizes AutoMapper, which greatly simplifies the process of mapping one type of object to another type.

Serilog

BlackSlope uses Serilog to perform all of its logging. Serilog has the ability to store log data in various ways— It uses “Sinks” to write logs out to different storage types. It provides sinks for many major storage types out-of-the-box, but it is also possible to create a custom sink if there isn’t one available for a specific storage type that you need. Again keep in mind that any specific settings can be put in the appsettings.json file in the Serilog section.

Application Insights

For performance management, logging, and monitoring, BlackSlope utilizes Application Insights. Serilog also has Sink for Application Insights. We will explain how to configure and use this sink in part two of this article series.

Versioning

Versioning is a simple service that allows you to get the version of the running API application. The version is exposed through a GET request to the /api/version endpoint.

Database (EF Core)

For Database queries, BlackSlope uses Entity Framework (EF) Core. EF Core has providers to support many database engines. To maintain proper segregation between layers, EF Core entities and queries should only be used within the Repository layer.

Middleware Components

Authentication Middleware

ASP.NET Core provides some tools and features to manage the security aspects of an application. One of the features is the Authentication middleware added as part of Core 2.0 release.

Besides adding the Authentication middleware, a service which implements the desired authentication mechanism based on an identity service should be registered. To demonstrate this in BlackSlope, Azure AD is being used as an identity service. The implementation will be described in part two of this article series.

CorrelationId Middleware

In distributed system architecture, requests are usually processed asynchronously. For example, a system or a service sends a request to another one, and the second system might put a request into a message broker queue which would be picked by a service to be processed, and there might be multiple other steps involved in processing that request.

We need a mechanism to be able to keep track of the transactions between all these asynchronous steps. This can be useful for logging, debugging, and other purposes. One approach to achieve this goal is using a CorrelationId that is added to requests so that each can be uniquely tracked throughout all the downstream systems.

Even in a simpler application architecture with fewer layers, requests are still usually processed asynchronously. Consider a very simple scenario when there is just a frontend web application using a backend API application to perform data-related actions; Even in this simple case, the CorrelationId can be a very useful tool for tracking unique requests in the system.

Exception Handling Middleware

Handling exceptions is an inevitable part of application development and maintenance. Exceptions can happen at any layer and at any time of execution. The challenge is implementing a way to centralize the exception handling process instead of implementing exception handlers all over the application code base. The approach that BlackSlope proposes to overcome this challenge is an exception handling middleware which can be added to the request processing pipeline.

Configuration Binding

BlackSlope uses a configuration binding mechanism to bind strongly typed objects to configuration values. In the Config directory, there can be found Classes that correspond to the sections in the appsettings.json file. For example, SwaggerConfig.cs has properties for Version , ApplicationName , and XmlFile , all of which correspond to a key-value pair in the Swagger section of the appsettings.json file.

Folder Structure and File Name

Besides being a reference architecture, BlackSlope provides some suggestions for structuring the folders, projects, and solution. In addition to the proposed structures, there are some suggestions regarding naming files as well.

Folder Structure

The below diagram depicts the suggested folder structure for the projects that make up a BlackSlope-based solution: