Modern readable coding
"Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer's intent but rather is full of crisp abstractions and straightforward lines of control."
~Grady Booch, author of 'Object-Oriented Analysis and Design with Applications'
The SolTechnology.Core repository contains a set of shared libraries. This is a foundation for CQRS-driven applications using basic Azure technologies. The libraries support a modern coding approach presented in the example applications.
| Documentation | Tags | NuGet |
|---|---|---|
| Core (foundation) |
Result, Error, Foundation
|
|
| API |
API, Web, Controllers
|
|
|
HTTP succeeds SolTechnology.Core.ApiClient — deprecated libraries
|
HTTP, Client, REST
|
|
| AUID |
GUID, UUID, ID, Identifier
|
|
| Authentication |
Auth, Security, Basic, API key
|
|
|
Blob Storage succeeds SolTechnology.Core.BlobStorage — deprecated libraries
|
Azure, Blob, Storage, no-SQL
|
|
| Cache |
Cache, Memory, Performance
|
|
| CQRS |
CQRS, Patterns, Architecture
|
|
| Hangfire |
Hangfire, Events, Jobs, Cron
|
|
|
Tale Framework succeeds SolTechnology.Core.Story — deprecated libraries
|
Workflow, Interactive, Tale Code
|
|
| Logging |
Logging, Diagnostics, Tracing
|
|
| Message Bus |
Azure, Messaging, Async, Queue
|
|
| SQL Database |
Database, SQL, ORM, Dapper, EF
|
Modular NUnit .Testing packages for component / integration tests — one companion per concern, all on
the shared SolTechnology.Core.Testing foundation. Reference from test projects only.
| Documentation | Tags | NuGet |
|---|---|---|
| Testing (foundation) |
Testing, NUnit, AutoFixture
|
|
| API Testing |
TestServer, Integration
|
|
| SQL Testing |
SQL, Postgres, Testcontainers
|
|
| HTTP Testing |
HTTP, WireMock, Mocks
|
|
| Redis Testing |
Redis, Cache, Testcontainers
|
|
| Blob Storage Testing |
Azure, Blob, Azurite
|
|
| Service Bus Testing |
Azure, Service Bus, Emulator
|
The idea of clean and readable code has stayed with me from the very beginning of my career. As a book lover and amateur writer, this is the most natural part of programming.
In the Tale Code approach, I am trying to summarize all the information about coding, design, automation, and configuration that I have learned over the years. The Tale Code rule is simple:
"Make your code a pleasure to read, like a tale."
~Adrian Aleksander Strugała
The sample application is the most common case that came to my mind. It's built of a user-facing API and a background worker responsible for fetching data and feeding the SQL database. The communication between these two is asynchronous and based on messages, as shown in the picture:
Code design is the main goal of Tale Code. Logical flow and code structure are described in detail, and it reads like a well-written story:
public class CalculateBestPathTale(IServiceProvider serviceProvider, ILogger<CalculateBestPathTale> logger)
: TaleHandler<CalculateBestPathQuery, CalculateBestPathContext, CalculateBestPathResult>(serviceProvider, logger),
IQueryHandler<CalculateBestPathQuery, CalculateBestPathResult>
{
protected override Tale<CalculateBestPathResult> Tell() =>
Open<InitiateContext>()
.Expect(ctx => ctx.NoOfCities > 1,
new NotFoundError { Message = "A route needs at least two cities." })
.Read<DownloadRoadData>()
.Read<FindProfitablePath>()
.Otherwise<JustOrderCities>() // no profitable route → just order by distance
.Read<SolveTsp>()
.WhenLost(error => logger.LogWarning("Best path calculation failed: {Error}", error.Message))
.Read<FormCalculateBestPathResult>()
.Finale(ctx => ctx.Output);
}I have summarized the knowledge and decisions into three chapters.
Enjoy your reading!
1. The Design
2. The Automation
3. The Quality
Some ending words

