• Stars
    star
    1,229
  • Rank 38,184 (Top 0.8 %)
  • Language
    C#
  • License
    MIT License
  • Created almost 4 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🕸 Yet Another .NET Clean Architecture, but for Microservices project. It uses Minimal Clean Architecture with DDD-lite, CQRS-lite, and just enough Cloud-native patterns apply on the simple eCommerce sample and run on Tye with Dapr extension 🍻

🔆 clean-architecture-dotnet

"Everything should be made as simple as possible, but not simpler." - Albert Einstein

"Mọi thứ đều nên đơn giản, càng đơn giản càng tốt, nhưng không nên đơn giản hơn bản chất của nó." - Vietnamese translated

We know that, and that's a reason we publish these libraries and samples. These are distillations with all best practices, tips, and tricks, and whatever made us spend a lot of time struggling to solve.

In the end of our journey, we would like to give these simplified and effortless libraries and samples as a reward for you. Enjoy the Minimal Clean Architecture, Domain-driven Design Lite, CQRS Lite, and just enough Cloud-native patterns!

Sparkline

DISCLAIMER

IMPORTANT: Because we are constantly evolving towards newly released technologies, .NET 6 is in the preview state so that it might change a lot in every release by the .NET team. So even we're trying to do the best for this OSS. But be careful if you use it for your project, and make sure that you do a stress test, benchmarking these libraries, and refactor them subsequently to adapt to your business carefully.

Feedback with improvements and pull requests from the community will be highly appreciated. Thank you!

Give a star

If you're using this repository for your learning, samples, workshop, or your project, please give a star. Thanks 👍

🎇 Business Usecases

🎇 High level context

🎇 ERD

🎇 Minimal DDD, CQRS, and Clean Architecture

  1. Domain-driven Design (a.k.a DDD) demonstrates it can help the business tidy and organized in many years. But it is hard to approach and use, we need to make it easier to use in real projects when we get started.

  2. Command and Query Responsibility Segregation (a.k.a CQRS) helps to separate components into command and query parts, but again it's really hard and might bloat when we get starting some of the project. We need something more lightweight, just like https://github.com/gautema/CQRSlite, but we might not need Event Sourcing in almost all projects.

  3. Clean Architecture helps the project structure easier to refactor and evolve in medium and big projects. Especially in the Microservice world, we always want to do and try with a lot of time in the project lifetime. The thing is boilerplate code in this kind of project to make components lose coupling.

=> When we jump in and set up the project for the Microservice approach. We want to apply all the best practices from the community, and some kind of patterns and architecture above sometimes makes us feel power off when start implements the first line of code which actually solves the business requirements. So the solution is we need something minimal and enough to get starting, and then when our business gets grows by the time, then we go back to add more. That's what's the practical way to go!

clean-architecture-dotnet is a collection of basic building blocks and project structure to help we get starting the project with less code boilerplate and effortless. We focus on the Microservice approach of how can we organize code, the project with the monorepo approach, and you can use it for modular monolith projects as well.

Reference to https://github.com/Sairyss/domain-driven-hexagon

💎 Prerequisites

♥️ Technical stacks

  • ✔️ .NET Core 6 - .NET Framework and .NET Core, including ASP.NET and ASP.NET Core
  • ✔️ MVC Versioning API - Set of libraries which add service API versioning to ASP.NET Web API, OData with ASP.NET Web API, and ASP.NET Core
  • ✔️ YARP - A toolkit for developing high-performance HTTP reverse proxy applications
  • ✔️ MediatR - Simple, unambitious mediator implementation in .NET
  • ✔️ EF Core - Modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations
  • ✔️ FluentValidation - Popular .NET validation library for building strongly-typed validation rules
  • ✔️ Swagger & Swagger UI - Swagger tools for documenting API's built on ASP.NET Core
  • ✔️ serilog - Simple .NET logging with fully-structured events
  • ✔️ Dapr dotnet-sdk - Dapr SDK for .NET
  • ✔️ RestEase - Easy-to-use typesafe REST API client library for .NET Standard 1.1 and .NET Framework 4.5 and higher, which is simple and customisable
  • ✔️ Polly - Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner
  • ✔️ Scrutor - Assembly scanning and decoration extensions for Microsoft.Extensions.DependencyInjection
  • ✔️ opentelemetry-dotnet - The OpenTelemetry .NET Client
  • ✔️ Blazor - WASM - Client web apps with C#
  • ✔️ BFF - Framework for ASP.NET Core to secure SPAs using the Backend-for-Frontend (BFF) pattern

🎇 All packages dependencies

✔️ Building blocks

+---N8T.Core
|   |   N8T.Core.csproj
|   |
|   +---Domain
|   |       Cqrs.cs
|   |       Entities.cs
|   |       Events.cs
|   |       Exceptions.cs
|   |
|   +---Helpers
|   |       DateTimeHelper.cs
|   |       GuidHelper.cs
|   |
|   +---Repository
|   |       IRepository.cs
|   |
|   \---Specification
|           And.cs
|           Extensions.cs
|           GridSpecificationBase.cs
|           ISpecification.cs
|           Negated.cs
|           Or.cs
|           PredicateBuilder.cs
|           SpecificationBase.cs
|
+---N8T.Infrastructure
|   |   AppOptions.cs
|   |   Extensions.cs
|   |   N8T.Infrastructure.csproj
|   |
|   +---Auth
|   |       AuthBehavior.cs
|   |       Extensions.cs
|   |       IAuthRequest.cs
|   |       ISecurityContextAccessor.cs
|   |       SecurityContextAccessor.cs
|   |
|   +---Bus
|   |   |   Extensions.cs
|   |   |   IEventBus.cs
|   |   |
|   |   \---Dapr
|   |       |   DaprEventBusOptions.cs
|   |       |
|   |       \---Internal
|   |               DaprEventBus.cs
|   |
|   +---Controller
|   |       BaseController.cs
|   |
|   +---Helpers
|   |       ConfigurationHelper.cs
|   |
|   +---Logging
|   |       Extensions.cs
|   |       LoggingBehavior.cs
|   |       TraceIdEnricher.cs
|   |
|   +---ServiceInvocation
|   |   \---Dapr
|   |           Extensions.cs
|   |
|   +---Status
|   |       Extensions.cs
|   |       StatusModel.cs
|   |
|   +---Swagger
|   |       ConfigureSwaggerOptions.cs
|   |       Extentions.cs
|   |       SwaggerDefaultValues.cs
|   |
|   +---TransactionalOutbox
|   |   |   Extensions.cs
|   |   |   OutboxEntity.cs
|   |   |
|   |   \---Dapr
|   |       |   DaprTransactionalOutboxOptions.cs
|   |       |   ITransactionalOutboxProcessor.cs
|   |       |
|   |       \---Internal
|   |               LocalDispatchedHandler.cs
|   |               TransactionalOutboxProcessor.cs
|   |
|   \---Validator
|           Extensions.cs
|           RequestValidationBehavior.cs
|           ValidationError.cs
|           ValidationException.cs
|           ValidationResultModel.cs
|
+---N8T.Infrastructure.EfCore
|   |   AppDbContextBase.cs
|   |   Consts.cs
|   |   DbContextDesignFactoryBase.cs
|   |   Extensions.cs
|   |   IDbFacadeResolver.cs
|   |   N8T.Infrastructure.EfCore.csproj
|   |   Repository.cs
|   |   TxBehavior.cs
|   |
|   \---Internal
|           DbContextMigratorHostedService.cs
|
\---N8T.Infrastructure.OTel
    |   Extensions.cs
    |   N8T.Infrastructure.OTel.csproj
    |
    \---MediatR
            OTelMediatROptions.cs
            OTelMediatRTracingBehavior.cs

✔️ Product service structure (microservice)

+---ProductService.Api
|   |   .dockerignore
|   |   appsettings.json
|   |   Dockerfile
|   |   ProductService.Api.csproj
|   |   Program.cs
|   |
|   +---Properties
|   |       launchSettings.json
|   |
|   \---V1
|           Anchor.cs
|           IntegrationEventHandler.cs
|           ProductController.cs
|           TransactionalOutboxProcessor.cs
|
+---ProductService.AppCore
|   |   Anchor.cs
|   |   ProductService.AppCore.csproj
|   |
|   +---Core
|   |   |   Product.cs
|   |   |   ProductCode.cs
|   |   |   Return.cs
|   |   |   ReturnReason.cs
|   |   |
|   |   \---Specs
|   |           ProductByIdQuerySpec.cs
|   |           ProductIsInStockSpec.cs
|   |           ProductListQuerySpec.cs
|   |           ProductReturnReasonSpec.cs
|   |
|   \---UseCases
|       +---Commands
|       |       CreateProduct.cs
|       |
|       \---Queries
|               GetProductById.cs
|               GetProducts.cs
|
\---ProductService.Infrastructure
    |   Anchor.cs
    |   Extensions.cs
    |   ProductService.Infrastructure.csproj
    |   readme.txt
    |
    \---Data
        |   MainDbContext.cs
        |   MainDbContextDesignFactory.cs
        |   Repository.cs
        |
        +---Migrations
        |       20210129103734_InitialProductionDb.cs
        |       20210129103734_InitialProductionDb.Designer.cs
        |       20210129104438_SeedInitData.cs
        |       20210129104438_SeedInitData.Designer.cs
        |       MainDbContextModelSnapshot.cs
        |
        \---Scripts
                20210129104438_SeedInitData.sql

🎇 Starting the APIs

$ cd samples
$ tye run
  • Public Apis:

Tye Dashboard: http://localhost:8000

Play around at restclient.http

No. Service name Service uri
1 YARP Gateway (downstream) http://localhost:5000
2 identity server https://localhost:5001
3 Web Blazor https://localhost:5002
4 product (upstream service) http://localhost:5003
5 customer (upstream service) http://localhost:5004
6 setting (upstream service) http://localhost:5005

🎇 Additional parts

Public CRUD interface

In medium and large software projects, we normally implement the CRUD actions over and over again. And it might take around 40-50% codebase just to do CRUD in the projects. The question is can we make standardized CRUD APIs, then we can use them in potential projects in the future? That is in my mind for a long time when I started and finished many projects, and I decide to take time to research and define the public interfaces for it as below

✔️ Common

public record ResultModel<T>(T Data, bool IsError = false, string? ErrorMessage = default);
public interface ICommand<T> : IRequest<ResultModel<T>> {}
public interface IQuery<T> : IRequest<ResultModel<T>> {}

✔️ [R]etrieve

// input model for list query (normally using for the table UI control with paging, filtering and sorting)
public interface IListQuery<TResponse> : IQuery<TResponse>
{
  public List<string> Includes { get; init; }
  public List<FilterModel> Filters { get; init; }
  public List<string> Sorts { get; init; }
  public int Page { get; init; }
  public int PageSize { get; init; }
}
// output model with items, total items, page and page size with serving for binding with the table UI control
public record ListResponseModel<T>(List<T> Items, long TotalItems, int Page, int PageSize);
public interface IItemQuery<TId, TResponse> : IQuery<TResponse>
{
  public List<string> Includes { get; init; }
  public TId Id { get; init; }
}

✔️ [C]reate

public interface ICreateCommand<TRequest, TResponse> : ICommand<TResponse>, ITxRequest
{
    public TRequest Model { get; init; }
}

✔️ [U]pdate

public interface IUpdateCommand<TRequest, TResponse> : ICommand<TResponse>, ITxRequest
{
  public TRequest Model { get; init; }
}

✔️ [D]elete

public interface IDeleteCommand<TId, TResponse> : ICommand<TResponse> where TId : struct
{
  public TId Id { get; init; }
}

Dapr components

✔️ Service Invocation

✔️ Event Bus

public interface IEventBus
{
  Task PublishAsync<TEvent>(TEvent @event, string[] topics = default, CancellationToken token = default) where TEvent : IDomainEvent;

  Task SubscribeAsync<TEvent>(string[] topics = default, CancellationToken token = default) where TEvent : IDomainEvent;
}
  • Dapr provider

✔️ Transactional Outbox

public class OutboxEntity
{
    [JsonInclude]
    public Guid Id { get; private set; }

    [JsonInclude]
    public DateTime OccurredOn { get; private set; }

    [JsonInclude]
    public string Type { get; private set; }

    [JsonInclude]
    public string Data { get; private set; }

    public OutboxEntity()
    {
        // only for System.Text.Json to deserialized data
    }

    public OutboxEntity(Guid id, DateTime occurredOn, IDomainEvent @event)
    {
        Id = id.Equals(Guid.Empty) ? Guid.NewGuid() : id;
        OccurredOn = occurredOn;
        Type = @event.GetType().FullName;
        Data = JsonConvert.SerializeObject(@event);
    }

    public virtual IDomainEvent RecreateMessage(Assembly assembly) => (IDomainEvent)JsonConvert.DeserializeObject(Data, assembly.GetType(Type)!);
}
  • Dapr provider

Sample pages

🎇 Credits

More Repositories

1

awesome-dotnet-core

🐝 A collection of awesome .NET core libraries, tools, frameworks and software
C#
18,711
star
2

clean-code-dotnet

🛁 Clean Code concepts and tools adapted for .NET
C#
6,204
star
3

go-coffeeshop

☕ A practical event-driven microservices demo built with Golang. Nomad, Consul Connect, Vault, and Terraform for deployment
Go
4,110
star
4

blog-core

Modular blog using Blazor with clean domain-driven design patterns
CSS
393
star
5

practical-dapr

A full-stack .NET microservices build on Dapr and Tye
C#
301
star
6

practical-dotnet-aspire

The practical .NET Aspire builds on the coffeeshop app business domain
C#
250
star
7

northwind-dotnet

A full-stack .NET 6 Microservices build on Minimal APIs and C# 10
C#
182
star
8

magazine-website

🐭 A magazine website (using .NET Core, ASP.NET Core, EF Core) with DDD, CQRS, microservices, asynchronous programming applied...
C#
169
star
9

webassembly-tour

⚙️ Take you through a tour of WebAssembly (WASM targets on WASI) with wasmCloud, Krustlet, WAGI, etc. 🌟 Give it a star if you like it.
Rust
149
star
10

GrpcJsonTranscoder

A filter which allows a RESTful JSON API client to send requests to .NET web server over HTTP and get proxied to a gRPC service
C#
121
star
11

coffeeshop-on-nomad

The .NET coffeeshop application runs on Docker, Nomad and Consul Connect
C#
108
star
12

shopping-cart-k8s

Service Mesh patterns for Microservices
C#
62
star
13

ShoppingCartDemo

The demo using MSA approach with .NET Core stack
C#
61
star
14

practical-opentelemetry

Make OpenTelemetry works on .NET Core with features such as tracing, logs and metrics on multiple protocols like HTTP/gRPC/UDP/TCP...
C#
59
star
15

bff-auth

The demonstration of modern authentication using BFF pattern and authorization enforcer using OPA
C#
51
star
16

coffeeshop-modular

.NET coffee shop application with modular approach
C#
47
star
17

magazine-website-mvc-5

A magazine website that implemented using ASP.NET MVC 5, Web API 2 and AngularJs
JavaScript
46
star
18

dapr-labs

Many forms of coffeeshop implemented by C# and Rust run on WebAssembly/WASI (Spin) + Dapr. ⭐️ Star to support our work!
C#
43
star
19

coffeeshop-on-dapr

The coffeeshop event-driven application is developed in C# and runs on Dapr (AKS)
C#
36
star
20

magazine-website-akka

The experiment on the akkadotnet
C#
23
star
21

coffeeshop-dapr-workflow

Opinionated coffeeshop application builds with Dapr workflow
C#
23
star
22

coolstore-moduliths

The coolstore website on modular monolith approach
C#
19
star
23

practical-cqrs-es

This repo contains all CQRS and ES with Clean Architecture on .NET Core
C#
16
star
24

modular-starter-kit

The starter kit with entire modular approach to help remove boilerplate code in developing
C#
15
star
25

fernet-dotnet

Fernet generates and verifies HMAC-based authentication tokens
C#
14
star
26

thangchung

11
star
27

thangchung.github.io

:trollface: thangchung zone
CSS
10
star
28

MessageBusLite

The lightweight version of message bus (event + command) on the .NET Core
C#
9
star
29

minimal-apis-csharp10

C# 10 and Minimal APIs demo for Vietnam .NET Conf 2021
C#
7
star
30

actix-dapr-rs

Make dapr-rs working with actix-web better
Rust
6
star
31

northwind-rs

The northwind application with the clean architecture approach powered by Rust
Rust
6
star
32

branca-dotnet

Authenticated and encrypted API tokens using modern crypto
C#
6
star
33

cinema-booking

Cinema Booking Application
JavaScript
5
star
34

todo-bicep

C#
5
star
35

authentication-authorization-dotnetcore-course

Authentication & Authorization in ASP.NET Core 2.0 (May 2018)
C#
4
star
36

tailwindonblazor-template

Makes Tailwind works with Blazor (live-reload mode)
C#
4
star
37

dapr-actors-experiment

This is an experiment that use Dapr actors on booking movie scenario
C#
4
star
38

todo-dotnet6

This is todo app on .NET 6 and deploy to Heroku
C#
4
star
39

presentations

My presentation slides and content
3
star
40

NUnit2Report

Export a report for NUnit framework
C#
3
star
41

NHibernate3Sample

The short example that wrote in NHibernate 3 Alpha 2, Fluent NHibernate, Autofac,...
3
star
42

owasp-quiz

The set of OWASP quiz
JavaScript
3
star
43

netcorelibs

The .NET Core best practices and tips for booting up the project development.
JavaScript
3
star
44

elm-quizzer

Quizzer Application
Elm
2
star
45

todo-atmos

Todo application on Atmos (WebAssembly with WASI)
Rust
2
star
46

graphql4net

The simple GraphQL for .NET developers.
C#
2
star
47

ConfORMSample

Using ConfORM for entity mappings and made mutiple database instances for SessionFactory management.
C#
2
star
48

magazine-website-lite

JavaScript
2
star
49

footballdata

C#
2
star
50

practical-dotnet-with-cna

C#
1
star
51

football-scores-lite

The run-time live football scores system
JavaScript
1
star
52

pocket-movies

Personal pocket movies that consume Rotten Tomatoes API for searching movies.
C#
1
star
53

gprc-blog

The modern blog totally builds with gRPC protocol
1
star
54

yew-parceljs

📦 The experiment web application builds with Yew (WebAssembly framework on Rust) + Tailwind and Parceljs v2
Rust
1
star
55

fermyon-vagrant-box

Vagrant box that contains Docker, Nomad, Consul, Spin to get starting with fermyon platform
1
star
56

coffeeshop-on-spinkube

1
star