Black Slope: Setup and Insights
Exploring the features of our robust, reliable, and efficient reference architecture for .NET Core projects
Black Slope is a Slalom reference architecture designed for building C# .NET Core APIs that my colleague Stephen Weinrich introduced in a previous post. In this entry, I will provide some insights into the specific features that are built into a Black Slope application, and how to make efficient use of them.
Setup
If you want to follow along by building a new Black Slope application on your machine, you can get started with the following steps:
- Install Visual Studio Community 2017, as Black Slope is a .NET Core 2.0 app.
- Install SQL Server Express 2017 for the application database needs.
- Go to the project’s Bitbucket.
- Checkout the code to your local machine.
- Execute the database migration script “Migrations.sh” located under the “Blackslope.Repositories.MovieRepository” project to populate database. The Movies database should be created in the localhost db server as the result of executing this script.
5. Press Ctrl + F5 to start the Visual Studio solution. You should see the page in the screenshot below on start.
Alternately, you can execute the build script (build.sh) followed by the run script (run.sh) to start the solution. Both of these scripts are located in the root location.
Features
1. Azure Active Directory Authentication: The application uses OAuth2 implicit grant and Authorization code grant. You can use authorization code grant type if the client application is a regular web app executed on a server. Implicit grant can be used if the project requirement is to use JavaScript based frameworks on the frontend. As shown below in the screenshot, you can generate the access token via Postman. All the details like Auth URL and Client Id can be retrieved from the Azure Portal (under “Active Directory”).
Subsequently, the application uses an authentication middleware component to consume the token and render access to the user.
2. Swagger: Black Slope integrates with Swagger, allowing an end user to visualize and interact with the API’s resources without having any of the implementation logic in place. This is automatically generated from your Swagger specification. This visual documentation makes backend implementation and client side consumption much easier. With Swagger integration, you can also add an Authorization header to your API requests:
3. Automapper: Instead of manually writing code to map objects of one type to another type, Black Slope uses a tool called Automapper that automatically handles mapping for you. It can easily map request models to domain models, domain models to DTOs, domain models to view models, and vice versa, all with minimal code. As a best practice in Black Slope, we have organized mapping configurations with profiles. Each mapping class inherits from Profile and its configuration is put into the constructor. Subsequently, profiles are added to the main mapper configuration by using assembly names.
4. Dependency Injection: Black Slope leverages built-in Dependency Injection support from.NET Core. As far as lifetimes for dependency injection instances in .Net Core applications are concerned, there are three possibilities:
- Singleton: This implies only a single instance will be created and shared by all consumers.
- Scoped: This implies that there will be one instance created per scope (i.e. one instance per request to the application).
- Transient: This implies that the components will not be shared but will be created each time they are requested.
Also, projects in Black Slope are responsible for creating their own resources. This approach decreases projects’ dependencies on one another, and allows any host to directly consume any project.
5. Application Insights: Black Slope integrates with Azure Application Insights to provide detailed performance monitoring, powerful alerting, and friendly dashboards to help ensure the application is available and performing as expected. To support integration, an Application Insights resource called “BlackSlope” is configured in the Microsoft Azure portal:
The instrumentation key provided by the Azure Resource gets configured in the appsettings.json file, and is used by Application Insights nuget package (Microsoft.ApplicationInsights.AspNetCore) which eventually gets consumed by the Black Slope application. The package includes standard modules that send telemetry, without you having to write any additional code.
If you want to send your own custom telemetry, you can use the TelemetryTracker class in the application. Also, switching on and off Application Insights is configurable in Black slope.
6. Serilog: Black Slope uses a diagnostic logging library called Serilog to gather structured logs from the application. One of the advantages of Serilog is that it is very simple, and you can easily configure it to log the events to console or file. To log the events to Application Insights, Black Slope uses the “Serilog.Sinks.ApplicationInsights” nuget package. Also, switching on and off console or file logs is configurable in Black slope.
7. Exception Handling: Black slope uses a custom exception handler middleware that creates a wrapper to return error responses. It covers both handled and unhandled exceptions. The custom error response contains two attributes:
a) List of errors returned.
b) Original request sent. This is optional and it can be used to debug logged response errors.
8. Fluent Validation: Data validation is quite critical when it comes to usability and data integrity of any software or application. Therefore, Black Slope integrates with Fluent Validation to validate objects that are passed in to controller actions by the model binding infrastructure. Integrating with Fluent Validation is relatively easy. The framework is quite versatile and offers advantages like the following:
a) Speed of development — it’s really easy to work with.
b) Easy to unit test validation rules.
c) Decoupled rules and models.
d) Speed of execution: Validation rules are immutable objects i.e. you can create them once and cache them.
9. XUnit: Black Slope uses XUnit.NET as a unit testing framework. The reasons for choosing XUnit were as follows:
a) Creates a new instance of the test class for every test that is run, so any code which is placed into the constructor of the test class will be run for every single test. This capability provides test isolation.
b) Enables running unit tests in parallel.
c) Has a unique and innovative way to divide tests into “facts” and “theories” to distinguish between “always true” and “true for the right data” conditions.
d) Removes the excessive usage of custom attributes.
In addition, Black Slope uses the Moq library, which allows you to write decoupled unit tests by mocking classes or interfaces. Black Slope also makes use of Autofixture to create test data.
10. Entity Framework Core 2.0: EF Core is cross-platform version of the popular Entity Framework data access technology. Therefore, Black Slope leverages Entity Framework Core for its ORM needs.
11. Rename Utility: Black Slope also contains a Rename Utility console project that enables a consumer of Black Slope to rename all the projects in the Black Slope application as per the needs of the project using this reference architecture. The Rename.sh file that is located in the root contains the necessary information to execute the rename utility program.
After executing this script using the example input above, you will notice that all the projects (including their namespace and assembly names) have been renamed to “Blockbuster”. Additionally, the root location contains a file called IgnoreExtensions.RenameUtitlity that contains all the extensions (dll, pdf, exe) for which the renaming will not applied.
12. EditorConfig: Black Slope contains an EditorConfig file that defines the coding styles for the project. This helps developers configure and enforce formatting and code style conventions to achieve consistent, more readable codebases. The EditorConfig file can be easily checked into source control and can be applied at repository and project levels. Any project that is consuming Black Slope as reference architecture can use this file to solve the problem of formatting code across teams.
CI/CD for Black Slope
1. Azure App Service/Visual Studio Team Services: Black Slope uses VSTS to build code and generate artifacts. Subsequently, these artifacts get published to different deployment slots (environments) via Azure App Service.
2. Docker: Black Slope also contains Docker support that will allow you to create a Docker image (Linux) and publish the code to a Docker container.
Roadmap for Black Slope
- Add ability to use Azure Key Vault to safeguard application settings like connection strings.
- Provide support for .NET 4.7.1 in addition to .NET Core 2.0.
Conclusions
Our hope is that Black Slope provides the best set of features and attributes to make it a reliable and efficient reference architecture for .NET projects. The out-of-the-box features it provides makes it quick to get started with a comprehensive, production-ready project, and eliminate much of the boilerplate that is often required to get going.