Recent Trend

data-science
? Path to a free self-taught education in Data Science!
FigmaToCode
Generate responsive pages and apps on Tailwind, Flutter and SwiftUI.
twitter-clone

my-arsenal-of-aws-security-tools
List of open source tools for AWS security: defensive, offensive, auditing, DFIR, etc.
InvoiceNet
Deep neural network to extract intelligent information from invoice documents.
macOS_Big_Sur_icons_replacements
Replacement icons for popular apps in the style of macOS Big Sur
AnimeGANv2
[Open Source]. The improved version of AnimeGAN.
bluezone-app
Bluezone - Bảo vệ mình, bảo vệ cộng đồng
awesome-sysadmin
A curated list of amazingly awesome open source sysadmin resources inspired by Awesome PHP.
facebook-scripts-dom-manipulation
An open-source project includes many scripts with no Access Token needed for Facebook users by directly manipulating the DOM.
MCinaBox
MCinaBox - A Minecraft Java Edition Launcher on Android
ai-economist
Foundation is a flexible, modular, and composable framework to model socio-economic behaviors and dynamics with both agents and governments. This framework can be used in conjunction with reinforcemen
TikTok-Shares-Botter
Adds TikTok Shares for you.
prefect
The easiest way to automate your data
tuya-convert
A collection of scripts to flash Tuya IoT devices to alternative firmwares
crush
Crush is an attempt to make a command line shell that is also a powerful modern programming language.
pyre-check
Performant type-checking for python.
polkadot
Polkadot Node Implementation
incyber

mesh
Cloud native service mesh for the rest of us.
V2rayU
V2rayU,基于v2ray核心的mac版客户端,用于科学上网,使用swift编写,支持vmess,shadowsocks,socks5等服务协议,支持订阅, 支持二维码,剪贴板导入,手动配置,二维码分享等
TLS-poison

heroicons
A set of free MIT-licensed high-quality SVG icons for UI development.
react-native
A framework for building native apps with React.
gui.cs
Console-based user interface toolkit for .NET applications.
Atlas
Atlas: End-to-End 3D Scene Reconstruction from Posed Images
aws-sdk-go
AWS SDK for the Go programming language.
charts
Curated applications for Kubernetes
pybind11
Seamless operability between C++11 and Python
mediapipe
MediaPipe is the simplest way for researchers and developers to build world-class ML solutions and applications for mobile, edge, cloud and the web.
proffy-discovery
A proposta do projeto é uma aplicação que possa ligar quem deseja aprender, com quer ensinar. É possível encontrar alunos para o que você leciona, ou encontrar o professor para aquela matéria que você
mixer
Add-on for real-time collaboration in Blender.
iOS-DeviceSupport
This repository holds the device support files for the iOS, and I will update it regularly.
simdjson
Parsing gigabytes of JSON per second
amplify-js
A declarative JavaScript library for application development using cloud services.
lottie-ios
An iOS library to natively render After Effects vector animations
Faze4-Robotic-arm
All files for 6 axis robot arm with cycloidal gearboxes .
xiaobaiyang

Javascript
A repository for All algorithms implemented in Javascript (for educational purposes only)
blog-post-workflow
Show your latest blog posts from any sources or StackOverflow activity on your GitHub profile/project readme automatically using the RSS feed
reverse-interview
Questions to ask the company during your interview
expo
An open-source platform for making universal native apps with React. Expo runs on Android, iOS, and the web.
955.WLB
955 不加班的公司名单 - 工作 955,work–life balance (工作与生活的平衡)
A-to-Z-Resources-for-Students
✅ Curated list of resources for college students
TDengine
An open-source big data platform designed and optimized for the Internet of Things (IoT).
django-jazzmin
Jazzy theme for Django
full-stack-fastapi-postgresql
Full stack, modern web application generator. Using FastAPI, PostgreSQL as database, Docker, automatic HTTPS and more.
Reflection_Summary
算法理论基础知识应知应会
Best-websites-a-programmer-should-visit
? Some useful websites for programmers.
bpytop
Linux/OSX/FreeBSD resource monitor
TelemetrySourcerer
Enumerate and disable common sources of telemetry used by AV/EDR.
instagrabber
InstaGrabber, the open-source Instagram client for Android. Originally by @AwaisKing.
pe_tree

Powershell-Scripts
Helpful list of powershell scripts I have found/created
drawio
Source to app.diagrams.net
analytics
Simple and privacy-friendly alternative to Google Analytics
pycaret
An open source, low-code machine learning library in Python
Ciphey
Automated decryption tool
Data-Science-Interview-Resources
A repository listing out the potential sources which will help you in preparing for a Data Science/Machine Learning interview. New resources added frequently.
ps4-ipv6-uaf

UNSAM_2020c2_Python
Curso de programación en Python - 2do cuatrimestre 2020 - UNSAM
gpu.js
GPU Accelerated JavaScript
how-to-secure-anything
How to systematically secure anything: a repository about security engineering
paperview
A high performance X11 animated wallpaper setter
core
? JAVClub - 让你的大姐姐不再走丢
home-cloud
The "cloud" at home
haoel.github.io

InstaPy
? Instagram Bot - Tool for automated Instagram interactions
bat
A cat(1) clone with wings.
DeOldify
A Deep Learning based project for colorizing and restoring old images (and video!)
educative.io_courses
this is downloadings of all educative.io free student subscription courses as pdf from GitHub student pack
rustlings
? Small exercises to get you used to reading and writing Rust code!
trackerslist
Updated list of public BitTorrent trackers
Statistical-Learning-Method_Code
手写实现李航《统计学习方法》书中全部算法
mobile
React Native client application for COVID Shield on iOS and Android
binary_search
A collection of improved binary search algorithms.
mirai

TapTap
Port of the double tap on back of device feature from Android 11 to any armv8 Android device
complete-javascript-course
Starter files, final projects and FAQ for my Complete JavaScript course
icons
Official open source SVG icon library for Bootstrap.
oneflow
OneFlow is a performance-centered and open-source deep learning framework.
ml-engineer-roadmap
WIP: Roadmap to becoming a machine learning engineer in 2020
hvmi
Hypervisor Memory Introspection Core Library
fhe-toolkit-linux
IBM Fully Homomorphic Encryption Toolkit For Linux
teenyicons
Tiny minimal 1px icons designed to fit in the smallest places.
project-citadel
An open source project management tool with Kanban boards
covid-alert-app
Exposure notification client application / Application client de notification d'exposition
ChromeAppHeroes
?谷粒-Chrome插件英雄榜, 为优秀的Chrome插件写一本中文说明书, 让Chrome插件英雄们造福人类~ ChromePluginHeroes, Write a Chinese manual for the excellent Chrome plugin, let the Chrome plugin heroes benefit the human~ 公众号「0加1」同步更新
SSPanel-Uim
SSPanel V3 魔改再次修改版
UnusualVolumeDetector
Gets the last 5 months of volume history for every ticker, and alerts you when a stock's volume exceeds 10 standard deviations from the mean within the last 3 days
formik
Build forms in React, without the tears ?
learn-cantrill-io-labs
Standard and Advanced Demos for learn.cantrill.io courses
TransCoder
Public release of the TransCoder research project https://arxiv.org/pdf/2006.03511.pdf
bounty-targets-data
This repo contains hourly-updated data dumps of bug bounty platform scopes (like Hackerone/Bugcrowd/Intigriti/etc) that are eligible for reports
CtCI-6th-Edition
Cracking the Coding Interview 6th Ed. Solutions
windows95
?? Windows 95 in Electron. Runs on macOS, Linux, and Windows.
SkyArk
SkyArk helps to discover, assess and secure the most privileged entities in Azure and AWS
interviews
Everything you need to know to get the job.
Android-Analysis
Getting Genymotion & Burpsuite setup for Android Mobile App Analysis
detext
DeText: A Deep Neural Text Understanding Framework for Ranking and Classification Tasks
awesome-java
A curated list of awesome frameworks, libraries and software for the Java programming language.
workflow

tye
Tye is a tool that makes developing, testing, and deploying microservices and distributed applications easier. Project Tye includes a local orchestrator to make developing microservices easier and the
java-design-patterns
Design patterns implemented in Java
java8-tutorial
Modern Java - A Guide to Java 8
generator-jhipster
JHipster is a development platform to quickly generate, develop, & deploy modern web applications & microservice architectures.
stayaway-app
Official repository for the STAYAWAY COVID mobile application
api-guidelines
Microsoft REST API Guidelines
win10script
This is the Ultimate Windows 10 Script from a creation from multiple debloat scripts and gists from github.
tutorials
Just Announced - "Learn Spring Security OAuth":
Otto
Otto makes machine learning an intuitive, natural language experience.? Facebook AI Challenge winner
first-order-model
This repository contains the source code for the paper First Order Motion Model for Image Animation
laravel-best-practices
Laravel best practices
hiring-without-whiteboards
⭐️ Companies that don't have a broken hiring process
PyTorch_YOLOv4
PyTorch implementation of YOLOv4
macintosh.js
A virtual Apple Macintosh with System 8, running in Electron. I'm sorry.
QuickCut
Your most handy video processing software
Super-mario-bros-PPO-pytorch
Proximal Policy Optimization (PPO) algorithm for Super Mario Bros
arrow
Apache Arrow is a cross-language development platform for in-memory data. It specifies a standardized language-independent columnar memory format for flat and hierarchical data, organized for efficien
swift
The Swift Programming Language
flutter
Flutter makes it easy and fast to build beautiful apps for mobile and beyond.
pikvm
Open and cheap DIY IP-KVM based on Raspberry Pi
ILSpy
.NET Decompiler with support for PDB generation, ReadyToRun, Metadata (&more) - cross-platform!
aluraflix
⚛️ Projeto feito durante a Imersão React da Alura
starship
☄?️ The minimal, blazing-fast, and infinitely customizable prompt for any shell!
leonsans
Leon Sans is a geometric sans-serif typeface made with code in 2019 by Jongmin Kim.
MCVmComputers
Order computer parts from a satellite orbiting around your minecraft world and build actual working computers with them!
CleanArchitecture.WebApi
An implementation of Clean Architecture for ASP.NET Core 3.1 WebAPI. Built with loosely coupled architecture and clean-code practices in mind.
NutShell
RISC-V SoC designed by students in UCAS
bartosz-basics-of-haskell
Code and exercises from Bartosz Milewski's Basics of Haskell Tutorial
fullstack-starterkit
GraphQL first full-stack starter kit with Node, React. Powered by TypeScript
movement-tracking
UP - DOWN - LEFT - RIGHT movement tracking.
OSCP-Exam-Report-Template-Markdown
? OSCP Exam Report Template in Markdown
react-native-instagram-clone
A React Native app - Clone Instagram mobile app (In progress)
felicette
Satellite imagery for dummies.
neovim
Vim-fork focused on extensibility and usability
machine-learning-roadmap
A roadmap connecting many of the most important concepts in machine learning, how to learn them and what tools to use to perform them.
python-cheatsheet
Comprehensive Python Cheatsheet
awesome-cold-showers
For when people get too hyped up about things
cutter
Free and Open Source Reverse Engineering Platform powered by radare2
ORB_SLAM3
ORB-SLAM3: An Accurate Open-Source Library for Visual, Visual-Inertial and Multi-Map SLAM
RustScan
Faster Nmap Scanning with Rust
openpilot
openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 85 supported car makes and models.
retinaface
The remake of the https://github.com/biubug6/Pytorch_Retinaface
awesome-gpt3

GitHub520
?让你“爱”上 GitHub,解决访问时图裂、加载慢的问题。
LeetcodeTop
汇总各大互联网公司容易考察的高频leetcode题?
angular-tetris
Tetris game built with Angular 10 and Akita ?
umi-core
UMI Core Go Library
RustScan
Faster Nmap Scanning with Rust
rpi-power-monitor
Raspberry Pi Power Monitor
umi-core-py
UMI Core Python Library
gpt3-sandbox
The goal of this project is to enable users to create cool web demos using the newly released OpenAI GPT-3 API with just a few lines of Python.
easy_rust
Rust explained using easy English
rengine
reNgine is an automated reconnaissance framework meant for gathering information during penetration testing of web applications. reNgine has customizable scan engines, which can be used to scan the we
industry-machine-learning
A curated list of applied machine learning and data science notebooks and libraries across different industries (by @firmai)
umi-core-js
UMI Core JS Library
bloatbox
☑️? Get rid of bloatware and clean your Windows 10 Start menu
umi-core-php
UMI Core PHP Library
proposal-record-tuple
ECMAScript proposal for the Record and Tuple value types. | Stage 2: it will change!
jetbrains-agent-latest
jetbrains全家桶永久激活破解,不需要修改host。完美破解!共享给各个程序员兄弟使用。适用于2020版本。
applied-ml
Curated papers, articles & videos on data science & machine learning applied in production, with results.
lotus
Implementation of the Filecoin protocol, written in Go
cat
CAT 作为服务端项目基础组件,提供了 Java, C/C++, Node.js, Python, Go 等多语言客户端,已经在美团点评的基础架构中间件框架(MVC框架,RPC框架,数据库框架,缓存框架等,消息队列,配置系统等)深度集成,为美团点评各业务线提供系统丰富的性能指标、健康状况、实时告警等。
fawkes
Fawkes, privacy preserving tool against facial recognition systems. More info at http://sandlab.cs.uchicago.edu/fawkes
terminal
The new Windows Terminal and the original Windows console host, all in the same place!
kibana
Your window into the Elastic Stack
terraform
Terraform enables you to safely and predictably create, change, and improve infrastructure. It is an open source tool that codifies APIs into declarative configuration files that can be shared amongst
gotraining
Go Training Class Material :
JavaFamily
【Java面试+Java学习指南】 一份涵盖大部分Java程序员所需要掌握的核心知识。
storybook
? The UI component workshop. Develop, document, & test for React, Vue, Angular, Ember, Web Components, & more!
awesome-remote-job
A curated list of awesome remote jobs and resources. Inspired by https://github.com/vinta/awesome-python
vueuse
? Collection of Composition API utils for Vue 2 and 3
fe-interview
前端面试每日 3+1,以面试题来驱动学习,提倡每日学习与思考,每天进步一点!每天早上5点纯手工发布面试题(死磕自己,愉悦大家),3000+道前端面试题全面覆盖,HTML/CSS/JavaScript/Vue/React/Nodejs/TypeScript/ECMAScritpt/Webpack/Jquery/小程序/软技能……
stock
stock,股票系统。使用python进行开发。
awesome-ml-courses
Awesome free machine learning and AI courses with video lectures.
laravel-boilerplate
The Laravel Boilerplate Project - https://laravel-boilerplate.com
reactjs-interview-questions
List of top 500 ReactJS Interview Questions & Answers....Coding exercise questions are coming soon!!
lx-music-desktop
一个基于 electron 的音乐软件
number-verifier
Number Verifier is a SMS verification tool that makes it easy to get a disposable SMS number and bypass SMS number verifications on any site.
CyberProfDevelopmentCovidResources
An awesome list of FREE resources for training, conferences, speaking, labs, reading, etc that are free all the time or during COVID-19 that cybersecurity professionals with downtime can take advantag
opentelemetry-specification
Specifications for OpenTelemetry
front-end-interview-handbook
? No bullshit answers to the famous h5bp "Front-end Job Interview Questions"
hello-algorithm
?????? 本项目包括:1、我写的 30w 字图解算法题典 2、100 张编程类超清晰思维导图 3、100 篇大厂面经汇总 4、各语言编程电子书 100 本 5、小浩算法网站源代码 ( ?? 国人项目上榜不容易,右上角助力一波!干就对了,奥利给 !??)
awesome-production-machine-learning
A curated list of awesome open source libraries to deploy, monitor, version and scale your machine learning
bypass-paywalls-chrome
Bypass Paywalls web browser extension for Chrome and Firefox.
awesome-mlops
A curated list of references for MLOps
airlines-to-china-covid-19
疫情期间的回国航班汇总
gpt-3-experiments
Test prompts for OpenAI's GPT-3 API and the resulting AI-generated texts.
NativeAlphaForAndroid

elyra
Elyra extends JupyterLab Notebooks with an AI centric approach.
myvision
Computer vision based ML training data generation tool. ?
computer-science
? Path to a free self-taught education in Computer Science!
abp
Open Source Web Application Framework for ASP.NET Core
Best-Flutter-UI-Templates
completely free for everyone. Its build-in Flutter Dart.
docs-next
Vue 3 core documentation
sodium-fabric
A Minecraft mod designed to improve frame rates and reduce micro-stutter
puppeteer-recorder
Puppeteer recorder is a Chrome extension that records your browser interactions and generates a Puppeteer script.
flutter_twitter_clone
Fully functional Twitter clone built in flutter framework using Firebase realtime database and storage
ailab
Experience, Learn and Code the latest breakthrough innovations with Microsoft AI
forem
For empowering community ?
hedgehog-lab
An open source scientific computing environment for JavaScript TOTALLY in your browser, matrix operations with GPU acceleration, TeX support, data visualization and symbolic computation.
Deep-Learning-Papers-Reading-Roadmap
Deep Learning papers reading roadmap for anyone who are eager to learn this amazing tech!
QA_bible
Библия QA это 163 страницы смеси ответов на вопросы с реальных собеседований на manual QA, перевода интересного контента с зарубежных ресурсов и агрегации материала с отечественных.
CTF_Hacker-Tools
CTF-渗透测试~工具合集
kong
? The Cloud-Native API Gateway
Pokedex
?️ Android Pokedex using Dagger Hilt, Motion, Coroutines, Flow, Jetpack (Room, ViewModel, LiveData) based on MVVM architecture.
ps4jb
PS4 6.72 jailbreak
PowerShell
PowerShell for every system!
capa
The FLARE team's open-source tool to identify capabilities in executable files.
react-use
React Hooks — ?
NewPipe
A libre lightweight streaming front-end for Android.
terraform-cdk
Define infrastructure resources using programming constructs and provision them using HashiCorp Terraform
developer-roadmap
Roadmap to becoming a web developer in 2020
ds-cheatsheets
List of Data Science Cheatsheets to rule the world
AppAuth-Android
Android client SDK for communicating with OAuth 2.0 and OpenID Connect providers.
data-scientist-roadmap
Toturial coming with "data science roadmap" graphe.
QuantumKatas
Tutorials and programming exercises for learning Q# and quantum computing
pwncat
Fancy reverse and bind shell handler
jquery
jQuery JavaScript Library
incubator-brpc
Industrial-grade RPC framework used throughout Baidu, with 1,000,000+ instances and thousands kinds of services, called "baidu-rpc" inside Baidu.
Rocket
A web framework for Rust.
protobuf
Protocol Buffers - Google's data interchange format
PaddleOCR
Awesome OCR toolkits based on PaddlePaddle (8.6M ultra-lightweight pre-trained model, support training and deployment among server, mobile, embeded and IoT devices)
Microsoft-threat-protection-Hunting-Queries
Sample queries for Advanced hunting in Microsoft Threat Protection
RxSwift
Reactive Programming in Swift
funds
自选基金助手是一款Chrome扩展,用来快速获取关注基金的实时数据,查看自选基金的实时估值情况
sherloq
An open-source digital image forensic toolset
phaser
Phaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.
awesome-github-profile-readme
A curated list of awesome Github Profile READMEs
Awesome-Hacking
A collection of various awesome lists for hackers, pentesters and security researchers
papers-we-love
Papers from the computer science community to read and discuss.
ZLMediaKit
A lightweight RTSP/RTMP/HTTP/HLS/HTTP-FLV/WebSocket-FLV/GB28181 server and client framework based on C++11
googleapis
Public interface definitions of Google APIs.
PSBits
Simple (relatively) things allowing you to dig a bit deeper than usual.
CodeGuide
? 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助,请给予支持(关注、点赞、分享)!
Javascript-Essentials

gradio
Rapidly create UIs for prototyping your machine learning model in 3 minutes
snapchat-clone
? A SnapChat clone built with React, Redux and Typescript. Styled with SASS. Tested with Cypress, Jest and Enzyme. Linted with Eslint and formatted with Prettier!
clean-architecture-manga
? Clean Architecture with .NET Core 3.1, C# 8 and React+Redux. Use cases as central organizing structure, completely testable, decoupled from frameworks
flink
Apache Flink
modular-monolith-with-ddd
Full Modular Monolith application with Domain-Driven Design approach.
pandas_exercises
Practice your pandas skills!
awesomefluttertips
❤️Flutter ❤️ tips and tricks ❤️ Awesome Flutter ❤️ tips and tricks ❤️
voila
Voilà turns Jupyter notebooks into standalone web applications
Flutter-Shopping-UI-Kit
I developed this application just for learning purpose. There are 20+ screen variations.
game_control

the-art-of-command-line
Master the command line, in one page
fastapi
FastAPI framework, high performance, easy to learn, fast to code, ready for production
paper_collection
Academic papers related to fuzzing, binary analysis and exploit dev, that I want to read or have already read
nndl.github.io
《神经网络与深度学习》 邱锡鹏著 Neural Network and Deep Learning
developer-handbook
An opinionated guide on how to become a professional Web/Mobile App Developer.
Tiny-XSS-Payloads
A collection of tiny XSS Payloads that can be used in different contexts.
100-Days-Of-ML-Code
100 Days of ML Coding
youtubeclone-backend
Youtube Clone Backend (Express + Sequelize)
node-react-ecommerce
Build ECommerce Website Like Amazon By React & Node & MongoDB
gin-vue-admin
基于gin+vue搭建的后台管理系统框架,集成jwt鉴权,权限管理,动态路由,分页封装,多点登录拦截,资源权限,上传下载,代码生成器,表单生成器等基础功能,五分钟一套CURD前后端代码包含数据库的快感你不要体验一下吗~,更多功能正在开发中,欢迎issue和pr~
ant-design-blazor
?A set of enterprise-class UI components based on Ant Design and Blazor WebAssembly.
spleeter
Deezer source separation library including pretrained models.
youtubeclone-frontend
Youtube Clone Frontend (React + Redux)
runtime
.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
pulsar
Apache Pulsar - distributed pub-sub messaging system
AnotherRedisDesktopManager
???A faster, better and more stable redis desktop manager, compatible with Linux, windows, mac. What's more, it won't crash when loading a large number of keys.
realworld
"The mother of all demo apps" — Exemplary fullstack Medium.com clone powered by React, Angular, Node, Django, and many more ?
checklist
Beyond Accuracy: Behavioral Testing of NLP models with CheckList
Complex-YOLOv4-Pytorch
The PyTorch Implementation based on YOLOv4 of the paper: "Complex-YOLO: Real-time 3D Object Detection on Point Clouds"
yandex-ui
Yandex UI Kit build on React and bem-react
prometheus
The Prometheus monitoring system and time series database.
Awesome-Profile-README-templates
A collection of awesome readme templates to display on your profile
RedditOS
A SwiftUI Reddit client for macOS Big Sur
facebook-ios-sdk
Used to integrate the Facebook Platform with your iOS & tvOS apps.
presto
The official home of the Presto distributed SQL query engine for big data
og-aws
? Amazon Web Services — a practical guide
copilot-cli
The AWS Copilot CLI is a tool for developers to build, release and operate production ready containerized applications on Amazon ECS and AWS Fargate.
How-to-create-a-csgo-cheating-program
CSGO游戏透视自瞄辅助实现教程
moby
Moby Project - a collaborative project for the container ecosystem to assemble container-based systems
torchsde
Differentiable SDE solvers with GPU support and efficient sensitivity analysis.
tsunami-security-scanner-plugins
This project aims to provide a central repository for many useful Tsunami Security Scanner plugins.
metersphere
MeterSphere 是一站式的开源企业级持续测试平台,涵盖测试跟踪、接口测试、性能测试、团队协作等功能
flokk
A fresh and modern Google Contacts manager that integrates with GitHub and Twitter.
free-for-dev
A list of SaaS, PaaS and IaaS offerings that have free tiers of interest to devops and infradev
emscripten
Emscripten: An LLVM-to-Web Compiler
grpc-java
The Java gRPC implementation. HTTP/2 based RPC
Team-Ares
Repository for all TeamARES POC code and tools.
cheatsheets
Official Matplotlib cheat sheets
fast
The adaptive interface system
 for modern web experiences.
azure-sdk-for-python
This repository is for active development of the Azure SDK for Python. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/en-us/python/azure/ or our
PowerJob
新一代分布式任务调度与计算框架,支持CRON、API、固定频率、固定延迟等调度策略,提供工作流来编排任务解决依赖关系,使用简单,功能强大,文档齐全,欢迎各位接入使用!
BottlEye
BottlEye is a usermode emulator for the popular anti-cheat BattlEye
cml
CML - Continuous Machine Learning or CI/CD for ML
tauri
Framework agnostic toolchain for building highly secure native apps that have tiny binaries and are very fast.
dlwpt-code
Code for the book Deep Learning with PyTorch by Eli Stevens, Luca Antiga, and Thomas Viehmann.
RevokeMsgPatcher
A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁(我已经看到了,撤回也没用了)
react-native-firebase
? A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
dragonwell8
Alibaba Dragonwell8 JDK
RADWIMPS
君の then-then-then 世は Promise で Future
Tiktok
高仿抖音APP
TaBERT
This repository contains source code for the TaBERT model, a pre-trained language model for learning joint representations of natural language utterances and (semi-)structured tables for semantic pars
dask-tutorial
Dask tutorial
HelloGitHub
Find pearls on open-source seashore 分享 GitHub 上有趣、入门级的开源项目
covid-tracker-app
COVID Tracker App Repository
digital-gardeners
Resources, links, projects, and ideas for gardeners tending their digital notes on the public interwebs
hackingtool
ALL IN ONE Hacking Tool For Hackers
ounotes
An Application built for students to access Notes , Question Papers , Syllabus and Resources for all Subjects of O.U (Osmania University) ??‍?
docker-cheat-sheet
Docker Cheat Sheet
blog
gamedev blog
CVE-2020-5902
CVE-2020-5902 BIG-IP
course-content
Summer course content for Neuromatch Academy
texthero
Text preprocessing, representation and visualization from zero to hero.
DeepLearning-500-questions
深度学习500问,以问答形式对常用的概率知识、线性代数、机器学习、深度学习、计算机视觉等热点问题进行阐述,以帮助自己及有需要的读者。 全书分为18个章节,50余万字。由于水平有限,书中不妥之处恳请广大读者批评指正。 未完待续............ 如有意合作,联系[email protected] 版权所有,违权必究 Tan 2018.06
edex-ui
A cross-platform, customizable science fiction terminal emulator with advanced monitoring & touchscreen support.
BYTEPATH

discord.js
A powerful JavaScript library for interacting with the Discord API
awesome-machine-learning
A curated list of awesome Machine Learning frameworks, libraries and software.
sweetviz
Visualize and compare datasets, target values and associations, with one line of code.
E-commerce-App-UI-Flutter
Nice and clean Online Shop app UI by using #Flutter.
rich
Rich is a Python library for rich text and beautiful formatting in the terminal.
javascript-algorithms
? Algorithms and data structures implemented in JavaScript with explanations and links to further readings
gitqlite
Query git repositories with SQL. Uses SQLite virtual tables and go-git
NonEuclidean
A Non-Euclidean Rendering Engine for 3D scenes.
org-roam
Rudimentary Roam replica with Org-mode
guietta

learngo
1000+ Hand-Crafted Go Examples, Exercises, and Quizzes
system-design-primer
Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.
pumpkin-book
《机器学习》(西瓜书)公式推导解析,在线阅读地址:https://datawhalechina.github.io/pumpkin-book
jexcel
jExcel is a lightweight vanilla javascript plugin to create amazing web-based interactive tables and spreadsheets compatible with Excel or any other spreadsheet software.
pure-bash-bible
? A collection of pure bash alternatives to external processes.
google-research
Google Research
Complete-Python-3-Bootcamp
Course Files for Complete Python 3 Bootcamp Course on Udemy
You-Dont-Know-JS
A book series on JavaScript. @YDKJS on twitter.
backstage
Backstage is an open platform for building developer portals
Warde
Simple and minimalistic server dashboard
warp
A super-easy, composable, web server framework for warp speeds.
midway
Midway is a Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Aliyun, Tencent-Cloud and traditional VM/Container.
EasyOCR
Ready-to-use OCR with 40+ languages supported including Chinese, Japanese, Korean and Thai
awesome-discord-communities
A curated list of awesome Discord communities for programmers
electron
Build cross-platform desktop apps with JavaScript, HTML, and CSS
jsonbase
A database software completely built as JSON files in backend. A powerful, portable and simple database works on top of JSON files. It is like a database software, currently having basic CRUD operatio
Ward
Simple and minimalistic server dashboard
breaking-bad-cast
App to show cast info for breaking bad
EssentialMath

J.A.R.V.I.S
python powered Intelligent System
PracticalSessions2020
Repository for tutorial sessions at EEML2020
flutterfire
? A collection of Firebase plugins for Flutter apps.
fenix
Firefox Preview
go-admin
基于Gin + Vue + Element UI的前后端分离权限管理系统脚手架(包含了:基础用户管理功能,jwt鉴权,代码生成器,RBAC资源控制,表单构建等)文档:http://doc.zhangwj.com/go-admin-site/ Demo: http://www.zhangwj.com/#/login
vitepress
Vite & Vue powered static site generator
zulip
Zulip server - powerful open source team chat
pygooglenews
If Google News had a Python library
UnblockNeteaseMusic
Revive unavailable songs for Netease Cloud Music
yapi
YApi 是一个可本地部署的、打通前后端及QA的、可视化的接口管理平台
telegraf
The plugin-driven server agent for collecting & reporting metrics.
cassandra-workshop-series
All materials for the Cassandra Workshop Series in a single place
just-react
React技术揭秘
rocketredis
A beautiful Redis GUI ?
Summer2021-Internships
Collection of Summer 2021 tech internships!
cubit
Cubit is a lightweight state management solution. It is a subset of the bloc package that does not rely on events and instead uses methods to emit new states.
vite
Native-ESM powered web dev build tool. It's fast.
electron-typescript-react
An Electron boilerplate including TypeScript, React, Jest and ESLint.
responsively-app
A modified browser that helps in responsive web development.
uno
Build Mobile, Desktop and WebAssembly apps with C# and XAML. Today. Open source and professionally supported.
material-ui
React components for faster and easier web development. Build your own design system, or start with Material Design.
BotBuilder-Samples
Welcome to the Bot Framework samples repository. Here you will find task-focused samples in C#, JavaScript and TypeScript to help you get started with the Bot Framework SDK!
OpenPCDet
OpenPCDet Toolbox for LiDAR-based 3D Object Detection.
jira-clone-angular
A simplified Jira clone built with Angular 9 and Akita
snipsnap
The ultimate snippets collection for VS Code
hacker-scripts
Based on a true story
v
Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. https://vlang.io
DataX

react-hook-form
? React Hooks for forms validation (Web + React Native)
nvm
Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions
datax-web
DataX集成可视化页面,选择数据源即可一键生成数据同步任务,支持批量创建RDBMS数据同步任务,集成开源调度系统,支持分布式、增量同步数据、实时查看运行日志、监控执行器资源、KILL运行进程、数据源信息加密等。
taro
开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5 等应用。 https://taro.jd.com/
cadmus
A GUI frontend for @werman's Pulse Audio real-time noise suppression plugin
PENTESTING-BIBLE
Updates to this repository will continue to arrive until the number of links reaches 10000 links & 10000 pdf files .Learn Ethical Hacking and penetration testing .hundreds of ethical hacking & penetra
hexapod
Blazing fast hexapod robot simulator with React and Plotly.
WickedEngine
C++ game engine focusing on modern rendering techniques and performance.
Silice
Silice is an open source language that simplifies writing algorithms fully exploiting FPGA architectures.
python-training
Python training for business analysts and traders
White-box-Cartoonization
Official tensorflow implementation for CVPR2020 paper “Learning to Cartoonize Using White-box Cartoon Representations”
ultimate-go
Ultimate Go study guide
cascadia-code
This is a fun, new monospaced font that includes programming ligatures and is designed to enhance the modern look and feel of the Windows Terminal.
rolling-rhino
Rolling Rhino; convert Ubuntu into a rolling release as seen on YouTube
precourse
A repo for the pre-course work at home exercises
python3-in-one-pic
Learn python3 in one picture.
TensorflowTTS
? TensorflowTTS: Real-Time State-of-the-art Speech Synthesis for Tensorflow 2
deep-learning-drizzle
Drench yourself in Deep Learning, Reinforcement Learning, Machine Learning, Computer Vision, and NLP by learning from these exciting lectures!!
SciencePlots
Matplotlib styles for scientific plotting
Pulse
A pendant to warn you when you touch your face
my-flutter-challenges
A collection of all my Flutter Challenges
super-productivity
To-do list & time tracker for programmers & other digital workers with Jira, Github and Gitlab integration
chat
Instant messaging server; backend in Go; iOS, Android, web, command line clients; chatbots
spektral
Graph Neural Networks with Keras and Tensorflow 2.
snowpack
The near-instant build tool for modern web apps.
Deep-learning-books
Books for machine learning, deep learning, math, NLP, CV, RL, etc
awesome-courses
? List of awesome university courses for learning Computer Science!
shardingsphere-elasticjob-lite
Distributed scheduled job framework
advanced-java
? 互联网 Java 工程师进阶知识完全扫盲:涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识,后端同学必看,前端同学也可学习
FreeDVDBoot
PlayStation 2 DVD Player Exploit
secretive
Store SSH keys in the Secure Enclave
cnn-explainer
Learning Convolutional Neural Networks with Interactive Visualization.
canal
阿里巴巴 MySQL binlog 增量订阅&消费组件
opencv
Open Source Computer Vision Library
gin
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
leetcode
LeetCode Solutions: A Record of My Problem Solving Journey.( leetcode题解,记录自己的leetcode解题之路。)
lemmy
? Building a federated alternative to reddit in rust
emigui
egui: Immediate mode GUI written in Rust, made for WASM
getx
Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
beego
beego is an open-source, high-performance web framework for the Go programming language.
vector
A lightweight and ultra-fast tool for building observability pipelines
Bug-Bounty-Toolz
BBT - Bug Bounty Tools
fullstack-course4
Example code for HTML, CSS, and Javascript for Web Developers Coursera Course
vnpy
基于Python的开源量化交易平台开发框架
honkit
? HonKit is building beautiful books using Markdown - Fork of GitBook
scrcpy
Display and control your Android device
formik
Build forms in React, without the tears ?
Mindustry
A sandbox tower defense game
arcore-depth-lab
ARCore Depth Lab is a set of Depth API samples that provides assets using depth for advanced geometry-aware features in AR interaction and rendering. (UIST 2020)
VTIL-Core
Virtual-machine Translation Intermediate Language
numerical-linear-algebra
Free online textbook of Jupyter notebooks for fast.ai Computational Linear Algebra course
Unlock-netease-cloud-music
解锁网易云音乐客户端变灰歌曲
FastSurfer
PyTorch implementation of FastSurferCNN
corona
Solar2D Game Engine main repository (ex Corona SDK)
OnJava8
《On Java 8》中文版,又名《Java编程思想》 第5版
Pwdb-Public
A collection of all the data i could extract from 1 billion leaked credentials from internet.
aviary.sh
Minimal distributed configuration management in bash
CalCAT
California COVID Assessment Tool
angular-cli
CLI tool for Angular
fgprof
? fgprof is a sampling Go profiler that allows you to analyze On-CPU as well as Off-CPU (e.g. I/O) time together.
terraform-provider-aws
Terraform AWS provider
elevator.js
Finally, a "back to top" button that behaves like a real elevator.
reverse-proxy
A toolkit for developing high-performance HTTP reverse proxy applications.
angular
One framework. Mobile & desktop.
data-science-ipython-notebooks
Data science Python notebooks: Deep learning (TensorFlow, Theano, Caffe, Keras), scikit-learn, Kaggle, big data (Spark, Hadoop MapReduce, HDFS), matplotlib, pandas, NumPy, SciPy, Python essentials, AW
linuxupskillchallenge
Learn the skills required to sysadmin a remote Linux server from the commandline.
PhotoGIMP
A Patch for GIMP 2.10+ for Photoshop Users
toydb
Distributed SQL database in Rust, written as a learning project
Active-Directory-Exploitation-Cheat-Sheet
A cheat sheet that contains common enumeration and attack methods for Windows Active Directory.
fluentui-system-icons
Fluent System Icons is a set of mobile platform icons from Microsoft
php-src
The PHP Interpreter
awesome-selfhosted
A list of Free Software network services and web applications which can be hosted locally. Selfhosting is the process of hosting and managing applications instead of renting from Software-as-a-Service
rasa
? Open source machine learning framework to automate text- and voice-based conversations: NLU, dialogue management, connect to Slack, Facebook, and more - Create chatbots and voice assistants
jax
Composable transformations of Python+NumPy programs: differentiate, vectorize, JIT to GPU/TPU, and more
awesome-interview-questions
A curated awesome list of lists of interview questions. Feel free to contribute! ?
PowerToys
Windows system utilities to maximize productivity
bookshelf
Build a ReactJS App workshop
Privilege-Escalation
This cheasheet is aimed at the CTF Players and Beginners to help them understand the fundamentals of Privilege Escalation with examples.
Papers-Literature-ML-DL-RL-AI
Highly cited and useful papers related to machine learning, deep learning, AI, game theory, reinforcement learning
ruby
The Ruby Programming Language [mirror]
brew
? The missing package manager for macOS (or Linux)
ALAE
[CVPR2020] Adversarial Latent Autoencoders
ant-design
? A UI Design Language and React UI library
itlwm
IntelWifi
Paper
High performance Spigot fork that aims to fix gameplay and mechanics inconsistencies
learnopencv
Learn OpenCV : C++ and Python Examples
tailwindcss
A utility-first CSS framework for rapid UI development.
esbuild
An extremely fast JavaScript bundler and minifier
react-query
⚛️ Hooks for fetching, caching and updating asynchronous data in React
3d-photo-inpainting
[CVPR 2020] 3D Photography using Context-aware Layered Depth Inpainting
nginx-ui
Nginx UI allows you to access and modify the nginx configurations files without cli.
SpringCloudLearning
《史上最简单的Spring Cloud教程源码》
raspberry-pi-os
Learning operating system development using Linux kernel and Raspberry Pi
abstreet
A traffic simulation game exploring how small changes to roads affect cyclists, transit users, pedestrians, and drivers.
spark
Apache Spark - A unified analytics engine for large-scale data processing
thingsboard
Open-source IoT Platform - Device management, data collection, processing and visualization.
MachineLearningECT
For better displaying html files and course material use this link
ZY-Player
▶️ 跨平台桌面端视频资源播放器.简洁无广告.免费高颜值. ?
wrk
Modern HTTP benchmarking tool
kugimiya-rainbow-fart
傲娇钉宫,鞭写鞭骂 - 钉宫理惠 vscode-rainbow-fart 扩展语音包
awesome-blazor
Resources for Blazor, a .NET web framework using C#/Razor and HTML that runs in the browser with WebAssembly.
L-ink_Card
Smart NFC & ink-Display Card
DeloresDev
Read all about it on GrumpyGamer:
IBMYes

elegant-emacs
A very minimal but elegant emacs (I think)
The-Open-Book

TeachYourselfCS-CN
TeachYourselfCS 的中文翻译 | A Chinese translation of TeachYourselfCS
tsunami-security-scanner
Tsunami is a general purpose network security scanner with an extensible plugin system for detecting high severity vulnerabilities with high confidence.
ThreeDPoseTracker

spring-boot-demo
spring boot demo 是一个用来深度学习并实战 spring boot 的项目,目前总共包含 65 个集成demo,已经完成 53 个。 该项目已成功集成 actuator(监控)、admin(可视化监控)、logback(日志)、aopLog(通过AOP记录web请求日志)、统一异常处理(json级别和页面级别)、freemarker(模板引擎)、thymeleaf(模板引擎)、Be
Better-Python-59-Ways
Code Sample of Book "Effective Python: 59 Specific Ways to Write Better Pyton" by Brett Slatkin
rpi-vk-driver
VK driver for the Raspberry Pi (Broadcom Videocore IV)
Face-Depixelizer
Face Depixelizer based on "PULSE: Self-Supervised Photo Upsampling via Latent Space Exploration of Generative Models" repository.
python-small-examples
告别枯燥,60 秒学会一个 Python 小例子
workshop
AI and Machine Learning with Kubeflow, Amazon EKS, and SageMaker
DeDRM_tools
DeDRM tools for ebooks
coding-interview-university
A complete computer science study plan to become a software engineer.
COVID-19
Novel Coronavirus (COVID-19) Cases, provided by JHU CSSE
Apollo-11
Original Apollo 11 Guidance Computer (AGC) source code for the command and lunar modules.
rust
Empowering everyone to build reliable and efficient software.
youtube-dl
Command-line program to download videos from YouTube.com and other video sites
arduino-esp32
Arduino core for the ESP32
awesomechat

OpenDiablo2
An open source re-implementation of Diablo 2
xxHash
Extremely fast non-cryptographic hash algorithm
public-apis
A collective list of free APIs for use in software and web development.
NotQuite0DayFriday
This is a repo which documents real bugs in real software to illustrate trends, learn how to prevent or find them more quickly.
kubernetes-goat
Kubernetes Goat is "Vulnerable by Design" Kubernetes Cluster.
project-based-learning
Curated list of project-based tutorials
pdown
PDown后继版,百度网盘代下载
vscode-rainbow-fart
一个在你编程时疯狂称赞你的 VSCode 扩展插件 | An VSCode extension that keeps giving you compliment while you are coding, it will checks the keywords of code to play suitable sounds.

modular-monolith-with-ddd

C# LINK
Full Modular Monolith application with Domain-Driven Design approach.

Modular Monolith with DDD

Full Modular Monolith .NET application with Domain-Driven Design approach.

Build Status

Table of contents

1. Introduction

  1.1 Purpose of this Repository

  1.2 Out of Scope

  1.3 Reason

  1.4 Disclaimer

  1.5 Give a Star

  1.6 Share It

2. Domain

  2.1 Description

  2.2 Conceptual Model

  2.3 Event Storming

3. Architecture

  3.1 High Level View

  3.2 Module Level View

  3.3 API and Module Communication

  3.4 Module Requests Processing via CQRS

  3.5 Domain Model Principles and Attributes

  3.6 Cross-Cutting Concerns

  3.7 Modules Integration

  3.8 Internal Processing

  3.9 Security

  3.10 Unit Tests

  3.11 Architecture Decision Log

  3.12 Architecture Unit Tests

  3.13 Integration Tests

  3.14 System Integration Testing

  3.15 Event Sourcing

4. Technology

5. How to Run

6. Contribution

7. Roadmap

8. Author

9. License

10. Inspirations and Recommendations

1. Introduction

1.1 Purpose of this Repository

This is a list of the main goals of this repository:

1.2 Out of Scope

This is a list of subjects which are out of scope for this repository:

1.3 Reason

The reason for creating this repository is the lack of something similar. Most sample applications on GitHub have at least one of the following issues:

To sum up, there are some very good examples, but there are far too few of them. This repository has the task of filling this gap at some level.

1.4 Disclaimer

Software architecture should always be created to resolve specific business problems. Software architecture always supports some quality attributes and at the same time does not support others. A lot of other factors influence your software architecture - your team, opinions, preferences, experiences, technical constraints, time, budget, etc.

Always functional requirements, quality attributes, technical constraints and other factors should be considered before an architectural decision is made.

Because of the above, the architecture and implementation presented in this repository is one of the many ways to solve some problems. Take from this repository as much as you want, use it as you like but remember to always pick the best solution which is appropriate to the problem class you have.

1.5 Give a Star

My primary focus in this project is on quality. Creating a good quality product involves a lot of analysis, research and work. It takes a lot of time. If you like this project, learned something or you are using it in your applications, please give it a star :star:. This is the best motivation for me to continue this work. Thanks!

1.6 Share It

There are very few really good examples of this type of application. If you think this repository makes a difference and is worth it, please share it with your friends and on social networks. I will be extremely grateful.

2. Domain

2.1 Description

Definition:

Domain - A sphere of knowledge, influence, or activity. The subject area to which the user applies a program is the domain of the software. Domain-Driven Design Reference, Eric Evans

The Meeting Groups domain was selected for the purposes of this project based on the Meetup.com system.

Main reasons for selecting this domain:

Meetings

The main business entities are Member, Meeting Group and Meeting. A Member can create a Meeting Group, be part of a Meeting Group or can attend a Meeting.

A Meeting Group Member can be an Organizer of this group or a normal Member.

Only an Organizer of a Meeting Group can create a new Meeting.

A Meeting has attendees, not attendees (Members which declare they will not attend the Meeting) and Members on the Waitlist.

A Meeting can have an attendee limit. If the limit is reached, Members can only sign up to the Waitlist.

A Meeting Attendee can bring guests to the Meeting. The number of guests allowed is an attribute of the Meeting. Bringing guests can be unallowed.

A Meeting Attendee can have one of two roles: Attendee or Host. A Meeting must have at least one Host. The Host is a special role which grants permission to edit Meeting information or change the attendees list.

Each Meeting Group must have an organizer with active Subscription. One organizer can cover 3 Meeting Groups by his Subscription.

Additionally, Meeting organizer can set an Event Fee. Each Meeting Attendee is obliged to pay the fee. All guests should be paid by Meeting Attendee too.

Administration

To create a new Meeting Group, a Member needs to propose the group. A Meeting Group Proposal is sent to Administrators. An Administrator can accept or reject a Meeting Group Proposal. If a Meeting Group Proposal is accepted, a Meeting Group is created.

Payments

Each Member who is the Payer can buy the Subscription. He needs to pay the Subscription Payment. Subscription can expire so Subscription Renewal is required (by Subscription Renewal Payment payment to keep Subscription active).

When the Meeting fee is required, the Payer needs to pay Meeting Fee (through Meeting Fee Payment).

Users

Each Administrator, Member and Payer is a User. To be a User, User Registration is required and confirmed.

Each User is assigned one or more User Role.

Each User Role has set of Permissions. A Permission defines whether User can invoke a particular action.

2.2 Conceptual Model

Definition:

Conceptual Model - A conceptual model is a representation of a system, made of the composition of concepts that are used to help people know, understand, or simulate a subject the model represents. Wikipedia - Conceptual model

Conceptual Model

2.3 Event Storming

While a Conceptual Model focuses on structures and relationships between them, behavior and events that occur in our domain are more important.

There are many ways to show behavior and events. One of them is a light technique called Event Storming which is becoming more popular. Below are presented 3 main business processes using this technique: user registration, meeting group creation and meeting organization.

Note: Event Storming is a light, live workshop. One of the possible outputs of this workshop is presented here. Even if you are not doing Event Storming workshops, this type of process presentation can be very valuable to you and your stakeholders.

User Registration process



Meeting Group creation


Meeting organization


Payments


3. Architecture

3.1 High Level View

Module descriptions:

Key assumptions:

  1. API contains no application logic
  2. API communicates with Modules using a small interface to send Queries and Commands
  3. Each Module has its own interface which is used by API
  4. Modules communicate each other only asynchronously using Events Bus - direct method calls are not allowed
  5. Each Module has it's own data in a separate schema - shared data is not allowed
    • Module data could be moved into separate databases if desired
  6. Modules can only have a dependency on the integration events assembly of other Module (see Module level view)
  7. Each Module has its own Composition Root, which implies that each Module has its own Inversion-of-Control container
  8. API as a host needs to initialize each module and each module has an initialization method
  9. Each Module is highly encapsulated - only required types and members are public, the rest are internal or private

3.2 Module Level View

Each Module has Clean Architecture and consists of the following submodules (assemblies):

Note: Application, Domain and Infrastructure assemblies could be merged into one assembly. Some people like horizontal layering or more decomposition, some don't. Implementing the Domain Model or Infrastructure in separate assembly allows encapsulation using the internal keyword. Sometimes Bounded Context logic is not worth it because it is too simple. As always, be pragmatic and take whatever approach you like.

3.3 API and Module Communication

The API only communicates with Modules in two ways: during module initialization and request processing.

Module initialization

Each module has a static Initialize method which is invoked in the API Startup class. All configuration needed by this module should be provided as arguments to this method. All services are configured during initialization and the Composition Root is created using the Inversion-of-Control Container.

public static void Initialize(
    string connectionString,
    IExecutionContextAccessor executionContextAccessor,
    ILogger logger,
    EmailsConfiguration emailsConfiguration)
{
    var moduleLogger = logger.ForContext("Module", "Meetings");

    ConfigureCompositionRoot(connectionString, executionContextAccessor, moduleLogger, emailsConfiguration);

    QuartzStartup.Initialize(moduleLogger);

    EventsBusStartup.Initialize(moduleLogger);
}

Request processing

Each module has the same interface signature exposed to the API. It contains 3 methods: command with result, command without result and query.

public interface IMeetingsModule
{
    Task<TResult> ExecuteCommandAsync<TResult>(ICommand<TResult> command);

    Task ExecuteCommandAsync(ICommand command);

    Task<TResult> ExecuteQueryAsync<TResult>(IQuery<TResult> query);
}

Note: Some people say that processing a command should not return a result. This is an understandable approach but sometimes impractical, especially when you want to immediately return the ID of a newly created resource. Sometimes the boundary between Command and Query is blurry. One example is AuthenticateCommand - it returns a token but it is not a query because it has a side effect.

3.4 Module Requests Processing via CQRS

Processing of Commands and Queries is separated by applying the architectural style/pattern Command Query Responsibility Segregation (CQRS).

Commands are processed using Write Model which is implemented using DDD tactical patterns:

internal class CreateNewMeetingGroupCommandHandler : ICommandHandler<CreateNewMeetingGroupCommand>
{
    private readonly IMeetingGroupRepository _meetingGroupRepository;
    private readonly IMeetingGroupProposalRepository _meetingGroupProposalRepository;

    internal CreateNewMeetingGroupCommandHandler(
        IMeetingGroupRepository meetingGroupRepository,
        IMeetingGroupProposalRepository meetingGroupProposalRepository)
    {
        _meetingGroupRepository = meetingGroupRepository;
        _meetingGroupProposalRepository = meetingGroupProposalRepository;
    }

    public async Task<Unit> Handle(CreateNewMeetingGroupCommand request, CancellationToken cancellationToken)
    {
        var meetingGroupProposal = await _meetingGroupProposalRepository.GetByIdAsync(request.MeetingGroupProposalId);

        var meetingGroup = meetingGroupProposal.CreateMeetingGroup();

        await _meetingGroupRepository.AddAsync(meetingGroup);

        return Unit.Value;
    }
}

Queries are processed using Read Model which is implemented by executing raw SQL statements on database views:

internal class GetAllMeetingGroupsQueryHandler : IQueryHandler<GetAllMeetingGroupsQuery, List<MeetingGroupDto>>
{
    private readonly ISqlConnectionFactory _sqlConnectionFactory;

    internal GetAllMeetingGroupsQueryHandler(ISqlConnectionFactory sqlConnectionFactory)
    {
        _sqlConnectionFactory = sqlConnectionFactory;
    }

    public async Task<List<MeetingGroupDto>> Handle(GetAllMeetingGroupsQuery request, CancellationToken cancellationToken)
    {
        var connection = _sqlConnectionFactory.GetOpenConnection();

        const string sql = "SELECT " +
                           "[MeetingGroup].[Id], " +
                           "[MeetingGroup].[Name], " +
                           "[MeetingGroup].[Description], " +
                           "[MeetingGroup].[LocationCountryCode], " +
                           "[MeetingGroup].[LocationCity]" +
                           "FROM [meetings].[v_MeetingGroups] AS [MeetingGroup]";
        var meetingGroups = await connection.QueryAsync<MeetingGroupDto>(sql);

        return meetingGroups.AsList();
    }
}

Key advantages:

Disadvantage:

For more information: Simple CQRS implementation with raw SQL and DDD

3.5 Domain Model Principles and Attributes

The Domain Model, which is the central and most critical part in the system, should be designed with special attention. Here are some key principles and attributes which are applied to Domain Models of each module:

  1. High level of encapsulation

    All members are private by default, then internal - only public at the very edge.

  2. High level of PI (Persistence Ignorance)

    No dependencies to infrastructure, databases, etc. All classes are POCOs.

  3. Rich in behavior

    All business logic is located in the Domain Model. No leaks to the application layer or elsewhere.

  4. Low level of Primitive Obsession

    Primitive attributes of Entites grouped together using ValueObjects.

  5. Business language

    All classes, methods and other members are named in business language used in this Bounded Context.

  6. Testable

    The Domain Model is a critical part of the system so it should be easy to test (Testable Design).

public class MeetingGroup : Entity, IAggregateRoot
{
    public MeetingGroupId Id { get; private set; }

    private string _name;

    private string _description;

    private MeetingGroupLocation _location;

    private MemberId _creatorId;

    private List<MeetingGroupMember> _members;

    private DateTime _createDate;

    private DateTime? _paymentDateTo;

    internal static MeetingGroup CreateBasedOnProposal(
        MeetingGroupProposalId meetingGroupProposalId,
        string name,
        string description,
        MeetingGroupLocation location, MemberId creatorId)
    {
        return new MeetingGroup(meetingGroupProposalId, name, description, location, creatorId);
    }

     public Meeting CreateMeeting(
            string title,
            MeetingTerm term,
            string description,
            MeetingLocation location,
            int? attendeesLimit,
            int guestsLimit,
            Term rsvpTerm,
            MoneyValue eventFee,
            List<MemberId> hostsMembersIds,
            MemberId creatorId)
        {
            this.CheckRule(new MeetingCanBeOrganizedOnlyByPayedGroupRule(_paymentDateTo));

            this.CheckRule(new MeetingHostMustBeAMeetingGroupMemberRule(creatorId, hostsMembersIds, _members));

            return new Meeting(this.Id,
                title,
                term,
                description,
                location,
                attendeesLimit,
                guestsLimit,
                rsvpTerm,
                eventFee,
                hostsMembersIds,
                creatorId);
        }

3.6 Cross-Cutting Concerns

To support Single Responsibility Principle and Don't Repeat Yourself principles, the implementation of cross-cutting concerns is done using the Decorator Pattern. Each Command processor is decorated by 3 decorators: logging, validation and unit of work.

Logging

The Logging decorator logs execution, arguments and processing of each Command. This way each log inside a processor has the log context of the processing command.

internal class LoggingCommandHandlerDecorator<T> : ICommandHandler<T> where T:ICommand
{
    private readonly ILogger _logger;
    private readonly IExecutionContextAccessor _executionContextAccessor;
    private readonly ICommandHandler<T> _decorated;

    public LoggingCommandHandlerDecorator(
        ILogger logger,
        IExecutionContextAccessor executionContextAccessor,
        ICommandHandler<T> decorated)
    {
        _logger = logger;
        _executionContextAccessor = executionContextAccessor;
        _decorated = decorated;
    }
    public async Task<Unit> Handle(T command, CancellationToken cancellationToken)
    {
        if (command is IRecurringCommand)
        {
            return await _decorated.Handle(command, cancellationToken);
        }
        using (
            LogContext.Push(
                new RequestLogEnricher(_executionContextAccessor),
                new CommandLogEnricher(command)))
        {
            try
            {
                this._logger.Information(
                    "Executing command {Command}",
                    command.GetType().Name);

                var result = await _decorated.Handle(command, cancellationToken);

                this._logger.Information("Command {Command} processed successful", command.GetType().Name);

                return result;
            }
            catch (Exception exception)
            {
                this._logger.Error(exception, "Command {Command} processing failed", command.GetType().Name);
                throw;
            }
        }
    }

    private class CommandLogEnricher : ILogEventEnricher
    {
        private readonly ICommand _command;

        public CommandLogEnricher(ICommand command)
        {
            _command = command;
        }
        public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
        {
            logEvent.AddOrUpdateProperty(new LogEventProperty("Context", new ScalarValue($"Command:{_command.Id.ToString()}")));
        }
    }

    private class RequestLogEnricher : ILogEventEnricher
    {
        private readonly IExecutionContextAccessor _executionContextAccessor;
        public RequestLogEnricher(IExecutionContextAccessor executionContextAccessor)
        {
            _executionContextAccessor = executionContextAccessor;
        }
        public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
        {
            if (_executionContextAccessor.IsAvailable)
            {
                logEvent.AddOrUpdateProperty(new LogEventProperty("CorrelationId", new ScalarValue(_executionContextAccessor.CorrelationId)));
            }
        }
    }
}

Validation

The Validation decorator performs Command data validation. It checks rules against Command arguments using the FluentValidation library.

internal class ValidationCommandHandlerDecorator<T> : ICommandHandler<T> where T:ICommand
{
    private readonly IList<IValidator<T>> _validators;
    private readonly ICommandHandler<T> _decorated;

    public ValidationCommandHandlerDecorator(
        IList<IValidator<T>> validators,
        ICommandHandler<T> decorated)
    {
        this._validators = validators;
        _decorated = decorated;
    }

    public Task<Unit> Handle(T command, CancellationToken cancellationToken)
    {
        var errors = _validators
            .Select(v => v.Validate(command))
            .SelectMany(result => result.Errors)
            .Where(error => error != null)
            .ToList();

        if (errors.Any())
        {
            var errorBuilder = new StringBuilder();

            errorBuilder.AppendLine("Invalid command, reason: ");

            foreach (var error in errors)
            {
                errorBuilder.AppendLine(error.ErrorMessage);
            }

            throw new InvalidCommandException(errorBuilder.ToString(), null);
        }

        return _decorated.Handle(command, cancellationToken);
    }
}

Unit Of Work

All Command processing has side effects. To avoid calling commit on every handler, UnitOfWorkCommandHandlerDecorator is used. It additionally marks InternalCommand as processed (if it is Internal Command) and dispatches all Domain Events (as part of Unit Of Work).

public class UnitOfWorkCommandHandlerDecorator<T> : ICommandHandler<T> where T:ICommand
{
    private readonly ICommandHandler<T> _decorated;
    private readonly IUnitOfWork _unitOfWork;
    private readonly MeetingsContext _meetingContext;

    public UnitOfWorkCommandHandlerDecorator(
        ICommandHandler<T> decorated,
        IUnitOfWork unitOfWork,
        MeetingsContext meetingContext)
    {
        _decorated = decorated;
        _unitOfWork = unitOfWork;
        _meetingContext = meetingContext;
    }

    public async Task<Unit> Handle(T command, CancellationToken cancellationToken)
    {
        await this._decorated.Handle(command, cancellationToken);

        if (command is InternalCommandBase)
        {
            var internalCommand =
                await _meetingContext.InternalCommands.FirstOrDefaultAsync(x => x.Id == command.Id,
                    cancellationToken: cancellationToken);

            if (internalCommand != null)
            {
                internalCommand.ProcessedDate = DateTime.UtcNow;
            }
        }

        await this._unitOfWork.CommitAsync(cancellationToken);

        return Unit.Value;
    }
}

3.7 Modules Integration

Integration between modules is strictly asynchronous using Integration Events and the In Memory Event Bus as broker. In this way coupling between modules is minimal and exists only on the structure of Integration Events.

Modules don't share data so it is not possible nor desirable to create a transaction which spans more than one module. To ensure maximum reliability, the Outbox / Inbox pattern is used. This pattern provides accordingly "At-Least-Once delivery" and "At-Least-Once processing".

The Outbox and Inbox is implemented using two SQL tables and a background worker for each module. The background worker is implemented using the Quartz.NET library.

Saving to Outbox:

Processing Outbox:

3.8 Internal Processing

The main principle of this system is that you can change its state only by calling a specific Command.

Commands can be called not only by the API, but by the processing module itself. The main use case which implements this mechanism is data processing in eventual consistency mode when we want to process something in a different process and transaction. This applies, for example, to Inbox processing because we want to do something (calling a Command) based on an Integration Event from the Inbox.

This idea is taken from Alberto's Brandolini's Event Storming picture called "The picture that explains “almost” everything" which shows that every side effect (domain event) is created by invoking a Command on Aggregate. See EventStorming cheat sheet article for more details.

Implementation of internal processing is very similar to implementation of the Outbox and Inbox. One SQL table and one background worker for processing. Each internally processing Command must inherit from InternalCommandBase class:

internal abstract class InternalCommandBase : ICommand
{
    public Guid Id { get; }

    protected InternalCommandBase(Guid id)
    {
        this.Id = id;
    }
}

This is important because the UnitOfWorkCommandHandlerDecorator must mark an internal Command as processed during committing:

public async Task<Unit> Handle(T command, CancellationToken cancellationToken)
{
    await this._decorated.Handle(command, cancellationToken);

    if (command is InternalCommandBase)
    {
        var internalCommand =
            await _meetingContext.InternalCommands.FirstOrDefaultAsync(x => x.Id == command.Id,
                cancellationToken: cancellationToken);

        if (internalCommand != null)
        {
            internalCommand.ProcessedDate = DateTime.UtcNow;
        }
    }

    await this._unitOfWork.CommitAsync(cancellationToken);

    return Unit.Value;
}

3.9 Security

Authentication

Authentication is implemented using JWT Token and Bearer scheme using IdentityServer. For now, only one authentication method is implemented: forms style authentication (username and password) via the OAuth2 Resource Owner Password Grant Type. It requires implementation of the IResourceOwnerPasswordValidator interface:

public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
    private readonly IUserAccessModule _userAccessModule;

    public ResourceOwnerPasswordValidator(IUserAccessModule userAccessModule)
    {
        _userAccessModule = userAccessModule;
    }

    public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
    {
        var authenticationResult = await _userAccessModule.ExecuteCommandAsync(new AuthenticateCommand(context.UserName, context.Password));
        if (!authenticationResult.IsAuthenticated)
        {
            context.Result = new GrantValidationResult(
                TokenRequestErrors.InvalidGrant,
                authenticationResult.AuthenticationError);
            return;
        }
        context.Result = new GrantValidationResult(
            authenticationResult.User.Id.ToString(),
            "forms",
            authenticationResult.User.Claims);
    }
}

Authorization

Authorization is achieved by implementing RBAC (Role Based Access Control) using Permissions. Permissions are more granular and a much better way to secure your application than Roles alone. Each User has a set of Roles and each Role contains one or more Permission. The User's set of Permissions is extracted from all Roles the User belongs to. Permissions are always checked on Controller level - never Roles:

[HttpPost]
[Route("")]
[HasPermission(MeetingsPermissions.ProposeMeetingGroup)]
public async Task<IActionResult> ProposeMeetingGroup(ProposeMeetingGroupRequest request)
{
    await _meetingsModule.ExecuteCommandAsync(
        new ProposeMeetingGroupCommand(
            request.Name,
            request.Description,
            request.LocationCity,
            request.LocationCountryCode));

    return Ok();
}

3.10 Unit Tests

Definition:

A unit test is an automated piece of code that invokes the unit of work being tested, and then checks some assumptions about a single end result of that unit. A unit test is almost always written using a unit testing framework. It can be written easily and runs quickly. It’s trustworthy, readable, and maintainable. It’s consistent in its results as long as production code hasn’t changed. Art of Unit Testing 2nd Edition Roy Osherove

Attributes of good unit test

Implementation

Unit tests should mainly test business logic (domain model):

Each unit test has 3 standard sections: Arrange, Act and Assert:

1. Arrange

The Arrange section is responsible for preparing the Aggregate for testing the public method that we want to test. This public method is often called (from the unit tests perspective) the SUT (system under test).

Creating an Aggregate ready for testing involves calling one or more other public constructors/methods on the Domain Model. At first it may seem that we are testing too many things at the same time, but this is not true. We need to be one hundred percent sure that the Aggregate is in a state exactly as it will be in production. This can only be ensured when we:

Isolation of external dependencies

There are 2 main concepts - stubs and mocks:

A stub is a controllable replacement for an existing dependency (or collaborator) in the system. By using a stub, you can test your code without dealing with the dependency directly.

A mock object is a fake object in the system that decides whether the unit test has passed or failed. It does so by verifying whether the object under test called the fake object as expected. There’s usually no more than one mock per test. Art of Unit Testing 2nd Edition Roy Osherove

Good advice: use stubs if you need to, but try to avoid mocks. Mocking causes us to test too many internal things and leads to overspecification.

2. Act

This section is very easy - we execute exactly one public method on aggregate (SUT).

3. Assert

In this section we check expectations. There are only 2 possible outcomes:

Simple example:

[Test]
public void NewUserRegistration_WithUniqueLogin_IsSuccessful()
{
    // Arrange
    var usersCounter = Substitute.For<IUsersCounter>();

    // Act
    var userRegistration =
        UserRegistration.RegisterNewUser(
            "login", "password", "[email protected]",
            "firstName", "lastName", usersCounter);

    // Assert
    var newUserRegisteredDomainEvent = AssertPublishedDomainEvent<NewUserRegisteredDomainEvent>(userRegistration);
    Assert.That(newUserRegisteredDomainEvent.UserRegistrationId, Is.EqualTo(userRegistration.Id));
}

[Test]
public void NewUserRegistration_WithoutUniqueLogin_BreaksUserLoginMustBeUniqueRule()
{
    // Arrange
    var usersCounter = Substitute.For<IUsersCounter>();
    usersCounter.CountUsersWithLogin("login").Returns(x => 1);

    // Assert
    AssertBrokenRule<UserLoginMustBeUniqueRule>(() =>
    {
        // Act
        UserRegistration.RegisterNewUser(
            "login", "password", "[email protected]",
            "firstName", "lastName", usersCounter);
    });
}

Advanced example:

[Test]
public void AddAttendee_WhenMemberIsAlreadyAttendeeOfMeeting_IsNotPossible()
{
    // Arrange
    var creatorId = new MemberId(Guid.NewGuid());
    var meetingTestData = CreateMeetingTestData(new MeetingTestDataOptions
    {
        CreatorId = creatorId
    });
    var newMemberId = new MemberId(Guid.NewGuid());
    meetingTestData.MeetingGroup.JoinToGroupMember(newMemberId);
    meetingTestData.Meeting.AddAttendee(meetingTestData.MeetingGroup, newMemberId, 0);

    // Assert
    AssertBrokenRule<MemberCannotBeAnAttendeeOfMeetingMoreThanOnceRule>(() =>
    {
        // Act
        meetingTestData.Meeting.AddAttendee(meetingTestData.MeetingGroup, newMemberId, 0);
    });
}

CreateMeetingTestData method is an implementation of SUT Factory described by Mark Seemann which allows keeping common creation logic in one place:

protected MeetingTestData CreateMeetingTestData(MeetingTestDataOptions options)
{
    var proposalMemberId = options.CreatorId ?? new MemberId(Guid.NewGuid());
    var meetingProposal = MeetingGroupProposal.ProposeNew(
        "name", "description",
        new MeetingGroupLocation("Warsaw", "PL"), proposalMemberId);

    meetingProposal.Accept();

    var meetingGroup = meetingProposal.CreateMeetingGroup();

    meetingGroup.UpdatePaymentInfo(DateTime.Now.AddDays(1));

    var meetingTerm = options.MeetingTerm ??
                      new MeetingTerm(DateTime.UtcNow.AddDays(1), DateTime.UtcNow.AddDays(2));

    var rsvpTerm = options.RvspTerm ?? Term.NoTerm;
    var meeting = meetingGroup.CreateMeeting("title",
        meetingTerm,
        "description",
        new MeetingLocation("Name", "Address", "PostalCode", "City"),
        options.AttendeesLimit,
        options.GuestsLimit,
        rsvpTerm,
        MoneyValue.Zero,
        new List<MemberId>(),
        proposalMemberId);

    DomainEventsTestHelper.ClearAllDomainEvents(meetingGroup);

    return new MeetingTestData(meetingGroup, meeting);
}

3.11 Architecture Decision Log

All Architectural Decisions (AD) are documented in the Architecture Decision Log (ADL).

More information about documenting architecture-related decisions in this way : https://github.com/joelparkerhenderson/architecture_decision_record

3.12 Architecture Unit Tests

In some cases it is not possible to enforce the application architecture, design or established conventions using compiler (compile-time). For this reason, code implementations can diverge from the original design and architecture. We want to minimize this behavior, not only by code review.

To do this, unit tests of system architecture, design, major conventions and assumptions have been written. In .NET there is special library for this task: NetArchTest. This library has been written based on the very popular JAVA architecture unit tests library - ArchUnit.

Using this kind of tests we can test proper layering of our application, dependencies, encapsulation, immutability, DDD correct implementation, naming, conventions and so on - everything what we need to test. Example:

More information about architecture unit tests here: https://blogs.oracle.com/javamagazine/unit-test-your-architecture-with-archunit

3.13 Integration Tests

Definition

"Integration Test" term is blurred. It can mean test between classes, modules, services, even systems - see this article (by Martin Fowler).

For this reason, the definition of integration test in this project is as follows:

Approach

Implementation

Integration test should test exactly one use case. One use case is represented by one Command/Query processing so CommandHandler/QueryHandler in Application layer is perfect starting point for running the Integration Test:

For each test, the following preparation steps must be performed:

  1. Clear database
  2. Prepare mocks
  3. Initialize testing module
[SetUp]
public async Task BeforeEachTest()
{
    const string connectionStringEnvironmentVariable =
        "ASPNETCORE_MyMeetings_IntegrationTests_ConnectionString";
    ConnectionString = Environment.GetEnvironmentVariable(connectionStringEnvironmentVariable, EnvironmentVariableTarget.Machine);
    if (ConnectionString == null)
    {
        throw new ApplicationException(
            $"Define connection string to integration tests database using environment variable: {connectionStringEnvironmentVariable}");
    }

    using (var sqlConnection = new SqlConnection(ConnectionString))
    {
        await ClearDatabase(sqlConnection);
    }

    Logger = Substitute.For<ILogger>();
    EmailSender = Substitute.For<IEmailSender>();
    EventsBus = new EventsBusMock();
    ExecutionContext = new ExecutionContextMock(Guid.NewGuid());

    PaymentsStartup.Initialize(
        ConnectionString,
        ExecutionContext,
        Logger,
        EventsBus,
        false);

    PaymentsModule = new PaymentsModule();
}

After preparation, test is performed on clear database. Usually, it is the execution of some (or many) Commands and:
a) running a Query or/and
b) verifying mocks
to check the result.

[TestFixture]
public class MeetingPaymentTests : TestBase
{
    [Test]
    public async Task CreateMeetingPayment_Test()
    {
        PayerId payerId = new PayerId(Guid.NewGuid());
        MeetingId meetingId = new MeetingId(Guid.NewGuid());
        decimal value = 100;
        string currency = "EUR";
        await PaymentsModule.ExecuteCommandAsync(new CreateMeetingPaymentCommand(Guid.NewGuid(),
            payerId, meetingId, value, currency));

        var payment = await PaymentsModule.ExecuteQueryAsync(new GetMeetingPaymentQuery(meetingId.Value, payerId.Value));

        Assert.That(payment.PayerId, Is.EqualTo(payerId.Value));
        Assert.That(payment.MeetingId, Is.EqualTo(meetingId.Value));
        Assert.That(payment.FeeValue, Is.EqualTo(value));
        Assert.That(payment.FeeCurrency, Is.EqualTo(currency));
    }
}

Each Command/Query processing is a separate execution (with different object graph resolution, context, database connection etc.) thanks to Composition Root of each module. This behavior is important and desirable.

3.14 System Integration Testing

Definition

System Integration Testing (SIT) is performed to verify the interactions between the modules of a software system. It involves the overall testing of a complete system of many subsystem components or elements.

Implementation

Implementation of system integration tests is based on approach of integration testing of modules in isolation (invoking commands and queries) described in the previous section.

The problem is that in this case we are dealing with asynchronous communication. Due to asynchrony, our test must wait for the result at certain times.

To correctly implement such tests, the Sampling technique and implementation described in the Growing Object-Oriented Software, Guided by Tests book was used:

An asynchronous test must wait for success and use timeouts to detect failure. This implies that every tested activity must have an observable effect: a test must affect the system so that its observable state becomes different. This sounds obvious but it drives how we think about writing asynchronous tests. If an activity has no observable effect, there is nothing the test can wait for, and therefore no way for the test to synchronize with the system it is testing. There are two ways a test can observe the system: by sampling its observable state or by listening for events that it sends out.

Test below:

  1. Creates Meeting Group Proposal in Meetings module
  2. Waits until Meeting Group Proposal to verification will be available in Administration module with 10 seconds timeout
  3. Accepts Meeting Group Proposal in Administration module
  4. Waits until Meeting Group is created in Meetings module with 15 seconds timeout
public class CreateMeetingGroupTests : TestBase
{
    [Test]
    public async Task CreateMeetingGroupScenario_WhenProposalIsAccepted()
    {
        var meetingGroupId = await MeetingsModule.ExecuteCommandAsync(
            new ProposeMeetingGroupCommand("Name",
            "Description",
            "Location",
            "PL"));

        AssertEventually(
            new GetMeetingGroupProposalFromAdministrationProbe(meetingGroupId, AdministrationModule), 
            10000);

        await AdministrationModule.ExecuteCommandAsync(new AcceptMeetingGroupProposalCommand(meetingGroupId));

        AssertEventually(
            new GetCreatedMeetingGroupFromMeetingsProbe(meetingGroupId, MeetingsModule),
            15000);
    }

    private class GetCreatedMeetingGroupFromMeetingsProbe : IProbe
    {
        private readonly Guid _expectedMeetingGroupId;

        private readonly IMeetingsModule _meetingsModule;

        private List<MeetingGroupDto> _allMeetingGroups;

        public GetCreatedMeetingGroupFromMeetingsProbe(
            Guid expectedMeetingGroupId, 
            IMeetingsModule meetingsModule)
        {
            _expectedMeetingGroupId = expectedMeetingGroupId;
            _meetingsModule = meetingsModule;
        }

        public bool IsSatisfied()
        {
            return _allMeetingGroups != null && 
                   _allMeetingGroups.Any(x => x.Id == _expectedMeetingGroupId);
        }

        public async Task SampleAsync()
        {
            _allMeetingGroups = await _meetingsModule.ExecuteQueryAsync(new GetAllMeetingGroupsQuery());
        }

        public string DescribeFailureTo() 
            => $"Meeting group with ID: {_expectedMeetingGroupId} is not created";
    }

    private class GetMeetingGroupProposalFromAdministrationProbe : IProbe
    {
        private readonly Guid _expectedMeetingGroupProposalId;

        private MeetingGroupProposalDto _meetingGroupProposal;

        private readonly IAdministrationModule _administrationModule;

        public GetMeetingGroupProposalFromAdministrationProbe(Guid expectedMeetingGroupProposalId, IAdministrationModule administrationModule)
        {
            _expectedMeetingGroupProposalId = expectedMeetingGroupProposalId;
            _administrationModule = administrationModule;
        }

        public bool IsSatisfied()
        {
            if (_meetingGroupProposal == null)
            {
                return false;
            }

            if (_meetingGroupProposal.Id == _expectedMeetingGroupProposalId &&
                _meetingGroupProposal.StatusCode == MeetingGroupProposalStatus.ToVerify.Value)
            {
                return true;
            }

            return false;
        }

        public async Task SampleAsync()
        {
            try
            {
                _meetingGroupProposal =
                    await _administrationModule.ExecuteQueryAsync(
                        new GetMeetingGroupProposalQuery(_expectedMeetingGroupProposalId));
            }
            catch
            {
                // ignored
            }
        }

        public string DescribeFailureTo()
            => $"Meeting group proposal with ID: {_expectedMeetingGroupProposalId} to verification not created";
    }
}

Poller class implementation (based on example in the book):

public class Poller
{
    private readonly int _timeoutMillis;

    private readonly int _pollDelayMillis;

    public Poller(int timeoutMillis)
    {
        _timeoutMillis = timeoutMillis;
        _pollDelayMillis = 1000;
    }

    public void Check(IProbe probe)
    {
        var timeout = new Timeout(_timeoutMillis);
        while (!probe.IsSatisfied())
        {
            if (timeout.HasTimedOut())
            {
                throw new AssertErrorException(DescribeFailureOf(probe));
            }

            Thread.Sleep(_pollDelayMillis);
            probe.SampleAsync();
        }
    }

    private static string DescribeFailureOf(IProbe probe)
    {
        return probe.DescribeFailureTo();
    }
}

3.15 Event Sourcing

Theory

During the implementation of the Payment module, Event Sourcing was used. Event Sourcing is a way of preserving the state of our system by recording a sequence of events. No less, no more.

It is important here to really restore the state of our application from events. If we collect events only for auditing purposes, it is an Audit Log/Trail - not the Event Sourcing.

The main elements of Event Sourcing are as follows:

Tool

In order not to reinvent the wheel, the SQL Stream Store library was used. As the documentation says:

SQL Stream Store is a .NET library to assist with developing applications that use event sourcing or wish to use stream based patterns over a relational database and existing operational infrastructure.

Like every library, it has its limitations and assumptions (I recommend the linked documentation chapter "Things you need to know before adopting"). For me, the most important 2 points from this chapter are:

  1. "Subscriptions (and thus projections) are eventually consistent and always will be." This means that there will always be an inconsistency time from saving the event to the stream and processing the event by the projector(s).
  2. "No support for ambient System.Transaction scopes enforcing the concept of the stream as the consistency and transactional boundary." This means that if we save the event to a events stream and want to save something in the same transaction, we must use TransactionScope. If we cannot use TransactionScope for some reason, we must accept the Eventual Consistency also in this case.

Other popular tools:

Implementation

There are 2 main "flows" to handle:

Command Handling

The whole process looks like this:

  1. We create / update an aggregate by creating an event
  2. We add changes to the Aggregate Store. This is the class responsible for writing / loading our aggregates. We are not saving changes yet.
  3. As part of Unit Of Work a) Aggregate Store adds events to the stream b) messages are added to the Outbox

Command Handler:

public class BuySubscriptionCommandHandler : ICommandHandler<BuySubscriptionCommand, Guid>
{
    private readonly IAggregateStore _aggregateStore;

    private readonly IPayerContext _payerContext;

    private readonly ISqlConnectionFactory _sqlConnectionFactory;

    public BuySubscriptionCommandHandler(
        IAggregateStore aggregateStore, 
        IPayerContext payerContext, 
        ISqlConnectionFactory sqlConnectionFactory)
    {
        _aggregateStore = aggregateStore;
        _payerContext = payerContext;
        _sqlConnectionFactory = sqlConnectionFactory;
    }

    public async Task<Guid> Handle(BuySubscriptionCommand command, CancellationToken cancellationToken)
    {
        var priceList = await PriceListProvider.GetPriceList(_sqlConnectionFactory.GetOpenConnection());

        var subscriptionPayment = SubscriptionPayment.Buy(
            _payerContext.PayerId,
            SubscriptionPeriod.Of(command.SubscriptionTypeCode),
            command.CountryCode,
            MoneyValue.Of(command.Value, command.Currency),
            priceList);

        _aggregateStore.AppendChanges(subscriptionPayment);

        return subscriptionPayment.Id;
    }
}

SubscriptionPayment Aggregate:

public class SubscriptionPayment : AggregateRoot
{
    private PayerId _payerId;

    private SubscriptionPeriod _subscriptionPeriod;

    private string _countryCode;

    private SubscriptionPaymentStatus _subscriptionPaymentStatus;

    private MoneyValue _value;

    protected override void Apply(IDomainEvent @event)
    {
        this.When((dynamic)@event);
    }

    public static SubscriptionPayment Buy(
        PayerId payerId,
        SubscriptionPeriod period,
        string countryCode,
        MoneyValue priceOffer,
        PriceList priceList)
    {
        var priceInPriceList = priceList.GetPrice(countryCode, period, PriceListItemCategory.New);
        CheckRule(new PriceOfferMustMatchPriceInPriceListRule(priceOffer, priceInPriceList));

        var subscriptionPayment = new SubscriptionPayment();

        var subscriptionPaymentCreated = new SubscriptionPaymentCreatedDomainEvent(
            Guid.NewGuid(),
            payerId.Value,
            period.Code,
            countryCode,
            SubscriptionPaymentStatus.WaitingForPayment.Code,
            priceOffer.Value,
            priceOffer.Currency);

        subscriptionPayment.Apply(subscriptionPaymentCreated);
        subscriptionPayment.AddDomainEvent(subscriptionPaymentCreated);

        return subscriptionPayment;
    }

    private void When(SubscriptionPaymentCreatedDomainEvent @event)
    {
        this.Id = @event.SubscriptionPaymentId;
        _payerId = new PayerId(@event.PayerId);
        _subscriptionPeriod = SubscriptionPeriod.Of(@event.SubscriptionPeriodCode);
        _countryCode = @event.CountryCode;
        _subscriptionPaymentStatus = SubscriptionPaymentStatus.Of(@event.Status);
        _value = MoneyValue.Of(@event.Value, @event.Currency);
    }

AggregateRoot base class:

public abstract class AggregateRoot
{
    public Guid Id { get; protected set; }

    public int Version { get; private set; }

    private readonly List<IDomainEvent> _domainEvents;

    protected AggregateRoot()
    {
        _domainEvents = new List<IDomainEvent>();

        Version = -1;
    }

    protected void AddDomainEvent(IDomainEvent @event)
    {
        _domainEvents.Add(@event);
    }

    public IReadOnlyCollection<IDomainEvent> GetDomainEvents() => _domainEvents.AsReadOnly();

    public void Load(IEnumerable<IDomainEvent> history)
    {
        foreach (var e in history)
        {
            Apply(e);
            Version++;
        }
    }

    protected abstract void Apply(IDomainEvent @event);

    protected static void CheckRule(IBusinessRule rule)
    {
        if (rule.IsBroken())
        {
            throw new BusinessRuleValidationException(rule);
        }
    }
}

Aggregate Store implementation with SQL Stream Store library usage:

public class SqlStreamAggregateStore : IAggregateStore
{
    private readonly IStreamStore _streamStore;

    private readonly List<IDomainEvent> _appendedChanges;

    private readonly List<AggregateToSave> _aggregatesToSave;

    public SqlStreamAggregateStore(
        ISqlConnectionFactory sqlConnectionFactory)
    {
        _appendedChanges = new List<IDomainEvent>();

        _streamStore =
            new MsSqlStreamStore(
                new MsSqlStreamStoreSettings(sqlConnectionFactory.GetConnectionString())
                    {
                        Schema = DatabaseSchema.Name
                });

        _aggregatesToSave = new List<AggregateToSave>();
    }

    public async Task Save()
    {
        foreach (var aggregateToSave in _aggregatesToSave)
        {
            await _streamStore.AppendToStream(
                GetStreamId(aggregateToSave.Aggregate),
                aggregateToSave.Aggregate.Version,
                aggregateToSave.Messages.ToArray());
        }

        _aggregatesToSave.Clear();
    }

    public async Task<T> Load<T>(AggregateId<T> aggregateId) where T : AggregateRoot
    {
        var streamId = GetStreamId(aggregateId);

        IList<IDomainEvent> domainEvents = new List<IDomainEvent>();
        ReadStreamPage readStreamPage;
        do
        {
            readStreamPage = await _streamStore.ReadStreamForwards(streamId, StreamVersion.Start, maxCount: 100);
            var messages = readStreamPage.Messages;
            foreach (var streamMessage in messages)
            {
                Type type = DomainEventTypeMappings.Dictionary[streamMessage.Type];
                var jsonData = await streamMessage.GetJsonData();
                var domainEvent = JsonConvert.DeserializeObject(jsonData, type) as IDomainEvent;

                domainEvents.Add(domainEvent);
            }
        } while (!readStreamPage.IsEnd);

        var aggregate = (T)Activator.CreateInstance(typeof(T), true);

        aggregate.Load(domainEvents);

        return aggregate;
    }

Events Projection

The whole process looks like this:

  1. Special class Subscriptions Manager subscribes to Events Store (using SQL Store Stream library)
  2. Events Store raises StreamMessageRecievedEvent
  3. Subscriptions Manager invokes all projectors
  4. If projector know how to handle given event, it updates particular read model. In current implementation it updates special table in SQL database.

SubscriptionsManager class implementation:

public class SubscriptionsManager
{
    private readonly IStreamStore _streamStore;

    public SubscriptionsManager(
        IStreamStore streamStore)
    {
        _streamStore = streamStore;
    }

    public void Start()
    {
        long? actualPosition;

        using (var scope = PaymentsCompositionRoot.BeginLifetimeScope())
        {
            var checkpointStore = scope.Resolve<ICheckpointStore>();

            actualPosition = checkpointStore.GetCheckpoint(SubscriptionCode.All);
        }

        _streamStore.SubscribeToAll(actualPosition, StreamMessageReceived);
    }

    public void Stop()
    {
        _streamStore.Dispose();
    }

    private static async Task StreamMessageReceived(
        IAllStreamSubscription subscription, StreamMessage streamMessage, CancellationToken cancellationToken)
    {
        var type = DomainEventTypeMappings.Dictionary[streamMessage.Type];
        var jsonData = await streamMessage.GetJsonData(cancellationToken);
        var domainEvent = JsonConvert.DeserializeObject(jsonData, type) as IDomainEvent;

        using var scope = PaymentsCompositionRoot.BeginLifetimeScope();

        var projectors = scope.Resolve<IList<IProjector>>();

        var tasks = projectors
            .Select(async projector =>
            {
                await projector.Project(domainEvent);
            });

        await Task.WhenAll(tasks);

        var checkpointStore = scope.Resolve<ICheckpointStore>();
        await checkpointStore.StoreCheckpoint(SubscriptionCode.All, streamMessage.Position);
    }
}

Example projector:

internal class SubscriptionDetailsProjector : ProjectorBase, IProjector
{
    private readonly IDbConnection _connection;

    public SubscriptionDetailsProjector(ISqlConnectionFactory sqlConnectionFactory)
    {
        _connection = sqlConnectionFactory.GetOpenConnection();
    }

    public async Task Project(IDomainEvent @event)
    {
        await When((dynamic) @event);
    }

    private async Task When(SubscriptionRenewedDomainEvent subscriptionRenewed)
    {
        var period = SubscriptionPeriod.GetName(subscriptionRenewed.SubscriptionPeriodCode);

        await _connection.ExecuteScalarAsync("UPDATE payments.SubscriptionDetails " +
                                                "SET " +
                                                    "[Status] = @Status, " +
                                                    "[ExpirationDate] = @ExpirationDate, " +
                                                    "[Period] = @Period " +
                                                "WHERE [Id] = @SubscriptionId",
            new
            {
                subscriptionRenewed.SubscriptionId,
                subscriptionRenewed.Status,
                subscriptionRenewed.ExpirationDate,
                period
            });
    }

    private async Task When(SubscriptionExpiredDomainEvent subscriptionExpired)
    {
        await _connection.ExecuteScalarAsync("UPDATE payments.SubscriptionDetails " +
                                             "SET " +
                                             "[Status] = @Status " +
                                             "WHERE [Id] = @SubscriptionId",
            new
            {
                subscriptionExpired.SubscriptionId,
                subscriptionExpired.Status
            });
    }

    private async Task When(SubscriptionCreatedDomainEvent subscriptionCreated)
    {
        var period = SubscriptionPeriod.GetName(subscriptionCreated.SubscriptionPeriodCode);

        await _connection.ExecuteScalarAsync("INSERT INTO payments.SubscriptionDetails " +
                                       "([Id], [Period], [Status], [CountryCode], [ExpirationDate]) " +
                                       "VALUES (@SubscriptionId, @Period, @Status, @CountryCode, @ExpirationDate)",
            new
            {
                subscriptionCreated.SubscriptionId,
                period,
                subscriptionCreated.Status,
                subscriptionCreated.CountryCode,
                subscriptionCreated.ExpirationDate
            });
    }
}

Sample view of Event Store

Sample Event Store view after execution of SubscriptionLifecycleTests Integration Test which includes following steps:

  1. Creating Price List
  2. Buying Subscription
  3. Renewing Subscription
  4. Expiring Subscription

looks like this (SQL Stream Store table - payments.Messages):

4. Technology

List of technologies, frameworks and libraries used for implementation:

5. How to Run

Example HTTP Request for an Access Token:

POST /connect/token HTTP/1.1
Host: localhost:5000

grant_type=password
&[email protected]
&password=testMemberPass
&client_id=ro.client
&client_secret=secret

This will fetch an access token for this user to make authorized API requests using the HTTP request header Authorization: Bearer <access_token>

If you use a tool such as Postman to test your API, the token can be fetched and stored within the tool itself and appended to all API calls. Check your tool documentation for instructions.

6. Contribution

This project is still under analysis and development. I assume its maintenance for a long time and I would appreciate your contribution to it. Please let me know by creating an Issue or Pull Request.

7. Roadmap

List of features/tasks/approaches to add:

Name Status Release date
Domain Model Unit Tests Completed 2019-09-10
Architecture Decision Log update Completed 2019-11-09
Integration automated tests Completed 2020-02-24
Migration to .NET Core 3.1 Completed 2020-03-04
System Integration Testing Completed 2020-03-28
More advanced Payments module Completed 2020-07-11
Event Sourcing implementation Completed 2020-07-11
API automated tests
FrontEnd SPA application
Meeting comments feature
Notifications feature
Messages feature

NOTE: Please don't hesitate to suggest something else or a change to the existing code. All proposals will be considered.

8. Author

Kamil Grzybek

Blog: https://kamilgrzybek.com

Twitter: https://twitter.com/kamgrzybek

LinkedIn: https://www.linkedin.com/in/kamilgrzybek/

GitHub: https://github.com/kgrzybek

9. License

The project is under MIT license.

10. Inspirations and Recommendations

Modular Monolith

Domain-Driven Design

Application Architecture

Software Architecture

System Architecture

Design

Craftsmanship

Testing

UML

Event Storming

Event Sourcing