Skip to content
Open in github.dev Open in a new github.dev tab Open in codespace

Navigate the complex landscape of .NET software architecture with our step-by-step, story-like guide. Unpack the interplay between modular monoliths, microservices, domain-driven design, and various architectural patterns. Go beyond the one-size-fits-all solutions and understand how to blend these approaches based on your unique needs.

MIT License
Public repository

Add file

Latest commit

441a7cd · Aug 15, 2026

History

1,495 Commits

Folders and files

NameName
Last commit message
Last commit date
Jan 25, 2026
Mar 29, 2025
Aug 15, 2026
Aug 15, 2026
Aug 15, 2026
Aug 15, 2026
Mar 13, 2023
Mar 13, 2023
Jul 11, 2023
Apr 23, 2026

Repository files navigation

Evolutionary Architecture演进式架构

Table of Contents目录
ea banner

realease

License Badge Stars Badge Commits Badge Last Commit Badge Issues Badge Pull Requests Badge Forks Badge Watchers Badge Discord Active

Objective目标

Problem

When searching for guidance on .NET solution architecture, you will find countless repositories and resources. Each tends to focus exclusively on their preferred approach, whether it is:当你寻找 .NET 解决方案架构指南时,会发现数不胜数的仓库和资源。每个资源往往只专注于其偏好的方法,无论是:

  • Clean, Onion or Hexagonal architecture整洁架构 (Clean Architecture)、洋葱架构 (Onion Architecture) 或六边形架构 (Hexagonal Architecture)

  • Tactical Domain-Driven Design战术领域驱动设计 (Tactical DDD)

  • Modular monolith模块化单体 (Modular monolith)

  • Microserverices微服务 (Microservices)

The real challenge? Most materials present their chosen approach as the universal solution, overlooking the nuanced reality of day-to-day software development. What is missing is a clear decision map to help you understand when and how to combine these different architectural elements and patterns.真正的挑战是什么?大多数材料将他们选择的方法呈现为万能解,却忽视了日常软件开发中微妙的现实。缺失的是一张清晰的决策图,帮助你理解何时以及如何组合这些不同的架构元素和模式。

The examples you do find often fall into two extremes: oversimplified demos that don’t reflect real-world complexity, or overwhelming enterprise-scale applications that are difficult to learn from. Even worse, some resources inadvertently perpetuate misconceptions by conflating different architectural concepts.你找到的示例通常走向两个极端:要么是无法反映现实复杂性的过度简化演示,要么是难以从中学习的庞大企业级应用。更糟糕的是,一些资源无意中混淆了不同的架构概念,从而加剧了误解。

We have all heard the phrase "it depends" so often it’s become a cliché. Yes, every decision depends on context-but that doesn’t mean we can’t develop heuristics to guide our choices.我们都听过“视情况而定”这句话,它已经成了陈词滥调。没错,每一个决策都取决于上下文,但这并不意味着我们不能制定启发式方法来指导我们的选择。

This repository offers something different: not just another static collection of patterns, but an evolutionary journey through the software architecture decision-making process. Here you will learn how to evaluate tradeoffs, combine approaches, and craft solutions that meet your specific needs at any given time.本仓库提供了一些不同的东西:不仅仅是又一个静态的模式集合,而是一段贯穿软件架构决策过程的演进之旅。在这里,你将学习如何评估权衡、组合方法,并打造出能随时满足你特定需求的解决方案。

Such an approach plays well with the dynamics of system implementation. Every development project faces a fundamental challenge that is called The Project Paradox:这种方法很好地契合了系统实施的动态性。每个开发项目都面临一个被称为“项目悖论”的基本挑战:

project paradox

When we start a project, we need to make crucial architectural decisions - exactly when we understand the domain the least. This creates a strong temptation to fall into one of two extremes - overcomplicated trap or oversimplified pitfall.当我们启动一个项目时,需要做出关键的架构决策——而这恰恰是我们对领域了解最少的时候。这极易诱使我们陷入两个极端之一——过度复杂的陷阱或过度简化的深渊。

Too often, we get swept up in tech trends and conference talks, leading us to preemptively adopt:我们太容易被技术趋势和会议演讲所左右,从而过早地采用:

  • Microservices before understanding our scaling needs在了解扩展需求之前就使用微服务

  • Complex orchestration systems复杂的编排系统

  • Data streaming solutions数据流解决方案

  • NoSQL databasesNoSQL 数据库

  • Caching layers缓存层

…​and more, "just in case we need them."……以及更多,仅仅是“以防万一”而采用的技术。

The result? We create our own complexity nightmare. New team members face a steep learning curve, costs spiral without clear benefits, and identifying performance bottlenecks becomes a maze of interconnected systems. We end up solving problems we don’t have yet while making it harder to solve the ones we do.结果呢?我们制造了自己的复杂性噩梦。新团队成员面临陡峭的学习曲线,成本在没有明显收益的情况下飙升,识别性能瓶颈变成了一个互联系统的迷宫。我们最终在解决尚未出现的问题,却让解决现有问题变得更加困难。

The opposite extreme, though less common, is equally problematic: starting too simple and staying there too long. This usually manifests as a monolith that grows unchecked until it becomes an unmaintainable "big ball of mud" - where new features simply get piled on without proper boundaries or structure.另一个极端虽然较少见,但也同样成问题:开始时过于简单,并且长期保持不变。这通常表现为一个不受限制地增长,直到变成无法维护的“大泥球”的单体应用——新功能只是在没有适当边界或结构的情况下被堆砌上去。

What we will show you is an evolutionary approach to architecture - one that grows with your understanding of the domain, and the complexity of your system. This path will help you build systems that are neither overengineered from the start nor too simplistic to scale.我们将向你展示一种演进式的架构方法——它随着你对领域理解的加深以及系统复杂性的增加而成长。这条路径将帮助你构建既不会在开始时过度设计,也不会因过于简单而无法扩展的系统。

Solution

Our approach unfolds like a story across four chapters, each building upon the last.我们的方法像一个故事一样分为四个章节展开,每一章都建立在前一章的基础上。

The entire repostiory reflects years of real-world experience, including the lessons we learned the hard way. Our goal is to guide you toward architecture that grows with your needs – neither too simplistic to scale nor too complex to maintain.整个仓库反映了我们多年的实战经验,包括我们从失败中汲取的教训。我们的目标是引导你走向一种能随需求增长的架构——既不会因过于简单而无法扩展,也不会因过于复杂而难以维护。

What we cover:我们涵盖的内容:

  • Analysis of a representative business domain (Fitness)代表性业务领域(健身)的分析

  • Domain-Driven Design (strategic and tactical)领域驱动设计(战略和战术)

  • Architectural patterns selection and evolution架构模式的选择与演进

  • Hybrid architecture combining modular monolith and microservices结合模块化单体和微服务的混合架构

  • Loose coupling松耦合

  • .NET backend implementation with minimal API使用 Minimal API 的 .NET 后端实现

  • Architecture decision log架构决策日志

  • Clean coding practices整洁代码实践

What we leave to you:我们留给你去选择的内容:

  • Frontend technology choice (React, Vue, Angular, Svelte, etc.)前端技术选择(React、Vue、Angular、Svelte 等)

  • Logging implementation (we recommend Serilog)日志实现(我们推荐 Serilog)

  • Contract testing (we suggest Pact Net)契约测试(我们建议使用 Pact Net)

Chapter 1: Initial Architecture: Focus On Simplicity第 1 章:初始架构:专注于简单性

In this chapter, we will show you how to lay the right foundation for your solution architecture. Our approach begins with a single project (Fitnet) that is thoughtfully organized from day one - but without overcomplicating things.在本章中,我们将向你展示如何为解决方案架构打下坚实的基础。我们的方法从一个从第一天起就经过深思熟虑组织的单一项目(Fitnet)开始,但不会过度复杂化。

The key is our vertical slice approach: each business process gets its own namespace, creating natural boundaries while keeping related code together. Think of it as organizing by what your software does rather than by technical categories.关键在于我们的垂直切片方法:每个业务流程都有自己的命名空间,在保持相关代码在一起的同时创造了自然的边界。可以将其理解为按软件的功能而非技术类别进行组织。

Why this works:为什么这样做有效:

  • Hit the ground running - spend time building features instead of debating project structures快速上手——将时间花在构建功能上,而不是争论项目结构

  • Everything for a process lives in one place (like SignContract) - no more jumping between Controllers, Entities, and Services folders流程相关的一切都放在同一个地方(例如 SignContract)——无需再在控制器、实体和服务的文件夹之间来回跳转

  • Future-proof your code - need to remove or relocate a feature? Just grab its namespace面向未来的代码——需要删除或重定位功能?只需移动其命名空间即可

Our modules talk to each other through a simple in-memory queue - just enough infrastructure to get the job done without overcomplicating things.我们的模块通过简单的内存队列进行通信——只需足够的设施来完成工作,而不会过度复杂化。

More information:更多信息:

Chapter 2: Modules Separation: Focus On Maintainability第 2 章:模块分离:专注于可维护性

In this chapter, we will tackle a familiar scenario: your initial architecture is starting to show its limits. Your codebase has matured, and reality has begun to diverge from your early assumptions. Some modules are more complex than anticipated, others simpler. Meanwhile, your growing team is wrestling with merge conflicts in your single project.在本章中,我们将处理一个熟悉的场景:你的初始架构开始显现其局限性。代码库已经成熟,现实情况开始偏离你早期的假设。有些模块比预期的复杂,有些则更简单。同时,你不断壮大的团队正在单一项目中为合并冲突而苦恼。

Time for the next evolution of your architecture. We will split our project into purpose-built projects that match each module’s actual needs.是时候进行下一次架构演进了。我们将项目拆分为符合每个模块实际需求的专用项目。

Simple modules stay simple:简单的模块保持简单:

  • Fitnet.ReportsFitnet.Reports

When all you need is straightforward data access and presentation? One project could be enough.当你只需要直接的数据访问和展示时,一个项目就足够了。

Middle-ground modules find their balance中间地带的模块找到平衡点

  • Fitnet.Passes.ApiFitnet.Passes.Api

  • Fitnet.Passes.DataAccessFitnet.Passes.DataAccess

Perfect for modules that need clean data access patterns but aren’t swimming in complex business rules.非常适合那些需要整洁数据访问模式但业务规则并不复杂的模块。

Complex domains get room to breathe复杂的领域获得喘息空间

  • Fitnet.Contracts.ApiFitnet.Contracts.Api

  • Fitnet.Contracts.ApplicationFitnet.Contracts.Application

  • Fitnet.Contracts.CoreFitnet.Contracts.Core

  • Fitnet.Contracts.InfrastructureFitnet.Contracts.Infrastructure

For those modules where business logic runs deep.适用于那些业务逻辑深厚的模块。

The beauty of this approach? Each module gets exactly the architecture it deserves - no more, no less. Meanwhile, our modules keep talking through the same in-memory queue, proving you don’t need to complicate everything at once.这种方法的精妙之处在于:每个模块都得到了它应有的架构——不多不少。同时,我们的模块继续通过同一个内存队列进行通信,证明了你不需要一次性把所有事情都搞复杂。

More information:

Chapter 3: Microservice Extraction: Focus On Growth第 3 章:微服务提取:专注于增长

In this chapter, we tackle a crucial evolution: knowing when and how to extract your first microservice. We will explore the real-world signals (we call them "disintegrators") that tell you it is time to let a module spread its wings and become independent.在本章中,我们将应对一个关键的演进:了解何时以及如何提取你的第一个微服务。我们将探索现实世界中的信号(我们称之为“解耦因子”),这些信号会告诉你,是时候让一个模块展翅高飞并独立运行了。

But extracting a microservice is just part of the story. We will also level up our communication game by replacing our trusty in-memory queue with a proper message queue component. This isn’t just about following trends - it is about building the robust communication backbone and ensure redundancy that your growing system needs to communicate with the new microservice.但提取微服务只是故事的一部分。我们还将通过用适当的消息队列组件替换我们可靠的内存队列来提升我们的通信水平。这不仅仅是为了追随潮流,而是为了构建健壮的通信骨干并确保冗余,这是你不断增长的系统与新微服务通信所必需的。

Along the way, you will pick up key microservice architecture concepts - not just the theory, but the practical knowledge you need to make it work in the real world.在此过程中,你将掌握关键的微服务架构概念——不仅仅是理论,还有你在现实世界中使其工作所需的实践知识。

More information:

Chapter 4: Applying Tactical Domain-Driven Design: Focus On Complexity第 4 章:应用战术领域驱动设计:专注于复杂性

In the final chapter of our journey, we will show you something powerful: you can grow into a domain model without starting from scratch. Getting there is more like evolution than revolution.在我们旅程的最后一章,我们将向你展示一些强大的内容:你可以成长为领域模型,而无需从零开始。到达目标的过程更像是演进,而不是革命。

Remember all that work you did early on - breaking down your domain, identifying subdomains, and organizing them into modules? Surprise! You have already done most of the heavy lifting for strategic Domain-Driven Design. That’s right - your foundation is stronger than you thought.还记得你早期所做的一切工作吗——拆解领域、识别子域并将它们组织成模块?惊喜!你已经完成了战略领域驱动设计的大部分繁重工作。没错——你的基础比你想象的要牢固。

Now comes the fun part: tactical DDD. Think of it as adding precision tools to your toolkit:现在是令人兴奋的部分:战术 DDD。可以将其视为在你的工具箱中添加精密工具:

  • Value Objects值对象 (Value Objects)

  • Entities实体 (Entities)

  • Aggregates聚合 (Aggregates)

  • Domain Events领域事件 (Domain Events)

The best part? You don’t need to apply every DDD concept to get value. It is like a chef’s kitchen - you don’t need every gadget to cook great meals, just the right ones for your dish.最棒的部分是?你不需要应用每一个 DDD 概念就能获得价值。这就像厨师的厨房——你不需要每样小工具都能做出美味佳肴,只需要适合你那道菜的工具即可。

More information:

Additional notes额外说明

Each chapter includes static code analysis to maintain code quality – a practice we strongly recommend for production environments.每一章都包含静态代码分析以维护代码质量——这是我们强烈建议在生产环境中采用的做法。

Note
All chapters represent various patterns and practices, but they are not hard and fast rules. Choose the approaches that meet your specific needs, or combine them to create the solution that fits your context. Think of this as your architectural compass, ready when you need it.

Domain领域

Overview

It is time to look at our domain. We have chosen a fitness domain as our example – one that seems familiar at first glance. Most people recognize the basic flow:是时候审视我们的领域了。我们选择了一个健身领域作为示例——乍一看似乎很熟悉。大多数人都能认出基本的流程:

  • Getting membership offers获取会员优惠

  • Preparing and signing contracts准备并签署合同

  • Getting access passes获取入场通行证

  • Attending fitness classes参加健身课程

But this surface-level familiarity can be deceptive.但这种表面的熟悉感可能会产生误导。

However, to identify the above processes, you usually need to analyze the domain with domain experts and break it down into smaller pieces called subdomains. Otherwise, there is a high risk of falling into a big ball of mud (or distributed mud) where everything is tightly coupled.然而,要识别上述流程,你通常需要与领域专家一起分析领域,并将其拆解为更小的部分,即子域。否则,极有可能陷入“大泥球”(或分布式泥球)的困境,导致所有东西都紧密耦合。

Note
The traditional domain expert is often pictured as a business representative – someone who lives and breathes the business processes every day. But don’t overlook another crucial source of domain expertise: your developers, especially those who have been in the trenches with legacy systems. Think about it: developers working with legacy code must understand not just how the system works, but why it works that way. They have seen the edge cases, handled the exceptions, and often know which business rules are truly critical versus which ones are historical artifacts.

What appears to be a straightforward domain actually conceals layers of complexity:看似直接的领域实际上隐藏着多层复杂性:

  • Pass expiration and renewal workflows通行证过期和续费工作流

  • Sophisticated discount strategies复杂的折扣策略

  • VIP member privilegesVIP 会员特权

  • Access control and rejection handling访问控制和拒绝处理

  • Membership status transitions会员状态转换

While we won’t model every aspect of a fitness studio’s operations (that would be a year-long endeavor!), we will demonstrate something more valuable: how to identify and separate key subdomains, and how to build extensible components that can grow with your needs. We have carefully chosen examples that are complex enough to illustrate real-world challenges while remaining manageable and instructive.虽然我们不会对健身房运营的每一个方面进行建模(那将是一项耗时一年的工作!),但我们将展示更有价值的东西:如何识别和分离关键子域,以及如何构建能随需求增长的可扩展组件。我们精心选择了足够复杂的示例来阐述现实世界的挑战,同时保持其可管理性和指导性。

Ultimately, you should be able to apply similar techniques to your own complex domains, regardless of industry.最终,无论身处哪个行业,你都应该能够将类似的技术应用到你自己的复杂领域中。

Subdomains

Every complex business domain becomes more manageable when broken down into smaller pieces. In domain modeling, we call these pieces Subdomains. Each subdomain represents a cohesive part of the domain.当被拆解为更小的部分时,每一个复杂的业务领域都会变得更易于管理。在领域建模中,我们将这些部分称为“子域”。每个子域都代表了领域的一个内聚部分。

subdomains theory

But how do we identify them?但是我们该如何识别它们呢?

While there are several effective approaches to domain decomposition, we particularly value two powerful techniques:虽然有几种有效的领域分解方法,但我们特别推崇两种强大的技术:

  • Event Storming: A collaborative modeling method that helps discover domain events and processes事件风暴 (Event Storming):一种协作建模方法,有助于发现领域事件和流程

  • Domain Storytelling: A visual approach to understanding business processes through storytelling领域叙事 (Domain Storytelling):一种通过讲故事来理解业务流程的可视化方法

Both techniques help reveal the natural boundaries in your system by focusing on business flows and interactions. We won’t focus on the details of either here, just the results you can achieve.这两种技术都通过关注业务流和交互,帮助揭示系统中的自然边界。我们这里不关注两者的细节,只关注你能取得的结果。

After careful analysis, we have identified the following subdomains that represent fitness domain:经过仔细分析,我们确定了代表健身领域的以下子域:

subdomains
Note
Watch out! You might have noticed we used simple names like Pass, Offer, and Contract for our subdomains. While these work for our example, they could lead you down the wrong path in real projects. These entity-like names can limit your thinking about what a subdomain represents. Instead, think in terms of business capabilities and processes. For example, instead of Passes, consider Passes Registration; rather than Offers, use Offers Management. This process-oriented naming becomes especially valuable when your domain grows. You might need to split a subdomain into more specific business processes – for instance, breaking Offers Management into Offer Publishing and Offer Advertising.

While there are many processes in each of the subdomains, we have chosen specific workflows to keep our example focused and meaningful:虽然每个子域中都有许多流程,但我们选择了特定的工作流,以保持示例的重点和意义:

subdomains processes

Here is where things get interesting: these six processes across four subdomains initially appear independent. However, this isolation represents a common architectural pitfall in real-world applications. To make our example more realistic and instructive, we need to address how these subdomains communicate with each other.有趣的地方来了:这四个子域中的六个流程最初看起来是独立的。然而,这种隔离代表了现实应用中一个常见的架构陷阱。为了使我们的示例更真实且具有指导意义,我们需要解决这些子域如何相互通信的问题。

subdomains communication

Our fitness studio system comes alive through two key interactions:我们的健身房系统通过两个关键交互变得生动起来:

  • First, when you sign a contract, the system automatically registers your access pass首先,当你签署合同时,系统会自动注册你的入场通行证

  • Second, when your membership nears expiration, it triggers the creation of an offer其次,当你的会员资格接近过期时,它会触发优惠信息的创建

These workflows demonstrate how our seemingly separate subdomains need to work together in real-world scenarios.这些工作流展示了我们看似独立的子域在现实场景中是如何需要协同工作的。

Now we need to somehow transform our subdomains into a technical solution. It is time to focus on bounded contexts.现在我们需要以某种方式将我们的子域转化为技术解决方案。是时候关注限界上下文了。

Bounded Contexts

To represent subdomains in your technical solution, you need a model. Often, we decide to just create a single, unified model for the entire solution. Unfortunately, this leads in future to a lot of issues because every subdomain operates in its own, and unique context.为了在技术解决方案中表示子域,你需要一个模型。通常,我们决定为整个解决方案创建一个单一的统一模型。不幸的是,这在未来会导致很多问题,因为每个子域都在其独特且特定的上下文中运行。

Let us explain.让我们解释一下。

Imagine having two subdomains of Workout Programming and Meal Planning and each operate with the Set term. However, it has very different meanings in each context:想象有两个子域:锻炼规划和膳食规划,它们都使用“组 (Set)”这个术语。然而,它在每个上下文中的含义截然不同:

  • In Workout Programming, a it refers to a specific number of exercise repetitions (like "3 sets of 10 pushups")在锻炼规划中,它指的是特定次数的运动重复(例如“3 组 10 次俯卧撑”)

  • In Meal Planning, it means a predefined collection of meals (like "the basic meal set includes breakfast, lunch, and two snacks")在膳食规划中,它意味着预定义的餐食集合(例如“基础餐食组包括早餐、午餐和两份零食”)

Using a single model across different subdomains forces your code to constantly check its context before applying business logic. This inevitable path leads to what developers jokingly call "ifology" - a maze of nested if-statements spreading throughout your codebase. Soon enough, what started as a simple intent to reuse code transforms into the dreaded "big ball of mud" or "spaghetti code" - where business rules become so intertwined that making even small changes becomes risky and time-consuming.在不同的子域中使用单一模型,会迫使你的代码在应用业务逻辑之前不断检查其上下文。这条不可避免的路径会导致开发人员戏称的“ifology”——嵌套的 if 语句迷宫遍布你的代码库。很快,最初重用代码的简单意图就会演变成可怕的“大泥球”或“意大利面条式代码”——业务规则变得如此交织,以至于进行哪怕很小的修改都变得充满风险且耗时。

Another approach is to divide your system into multiple models. Each model will represent its ubiquitous language, business capabilities, and rules. This approach allows models to be extended independently without affecting the others. This way each model becomes a separate bounded context.另一种方法是将系统划分为多个模型。每个模型都将代表其通用语言、业务能力和规则。这种方法允许模型独立扩展,而不会影响其他模型。这样,每个模型都成为一个独立的限界上下文。

Important
Don’t be misled by the word "ubiquitous" in "ubiquitous language" - it is a common trap that catches many development teams. It is only universal (ubiquitous) within its specific bounded context, not across your entire system.

While working on software systems, you will usually face one of the following cases:在处理软件系统时,你通常会面临以下情况之一:

  • Multiple subdomains are represented by a single bounded context多个子域由一个限界上下文表示

  • Each subdomain is represented by a single bounded context每个子域由一个限界上下文表示

In our implementation, we have made a deliberate architectural choice: each subdomain operates as its own bounded context, establishing clear boundaries and independence. However, it is important to note that real-world domains aren’t always this neat. Sometimes multiple subdomains naturally group together into a single bounded context. Take, for example, how Progress Tracking, and Virtual Coaching might naturally combine into a "Personalized Training" bounded context.在我们的实现中,我们做出了一个深思熟虑的架构选择:每个子域作为一个独立的限界上下文运行,建立了清晰的边界和独立性。然而,需要注意的是,现实世界的领域并不总是如此整洁。有时,多个子域会自然地组合成一个限界上下文。例如,进度跟踪和虚拟教练如何自然地组合成一个“个性化训练”限界上下文。

One of the really useful tools while working on the definition of bounded contexts is Bounded Context Canvas from DDD Crew.在定义限界上下文时,一个非常有用的工具是来自 DDD Crew 的限界上下文画布 (Bounded Context Canvas)。

When you are finished defining all the bounded contexts, you should define the communication and integration map between them. You can use a Context Map to do this, but we will not focus on explaining it here.当你定义完所有限界上下文后,你应该定义它们之间的通信和集成映射。你可以使用上下文映射 (Context Map) 来完成此操作,但我们在此不重点解释它。

Repository Structure仓库结构

Overview

Think of this repository as a novel rather than a technical manual. Each chapter builds naturally on the last, telling the story of how a real-world application evolves from its first lines of code to a mature, well-architected system. Simply follow the chapters in order, like turning the pages of a book, and see how each architectural decision naturally leads to the next. This "story-first" approach helps you understand not only what we built, but also why we made each choice along the way (supported by the architecture decision log).将此仓库视为一部小说,而不是技术手册。每一章都自然地建立在前一章的基础上,讲述了一个现实世界的应用程序如何从第一行代码演进为一个成熟、架构良好的系统的故事。只需按照章节顺序阅读,就像翻书一样,看看每一个架构决策是如何自然地引出下一个决策的。这种“故事优先”的方法可以帮助你理解我们不仅构建了什么,还理解了我们为何在过程中做出每一个选择(并由架构决策日志提供支持)。

How To Navigate?

This repository is organized with crystal-clear simplicity: beyond this main README and its supporting assets, you will find four key chapters that tell our evolutionary story:本仓库的组织非常清晰:除了这个主 README 及其支持资产外,你还会发现四个讲述我们演进故事的关键章节:

In each folder you will find the same root solution, but expanded:在每个文件夹中,你都会找到相同的根解决方案,但有所扩展:

  • Chapter 1: Your starting point - a simple, initial architecture第 1 章:你的起点——一个简单的初始架构

  • Chapter 2: Growing pains lead to project separation第 2 章:成长的烦恼导致项目分离

  • Chapter 3: Taking the microservice leap and upgrading communication第 3 章:迈向微服务并升级通信

  • Chapter 4: Embracing tactical DDD in a maturing microservice第 4 章:在成熟的微服务中拥抱战术 DDD

Each chapter comes with its own detailed README - think of it as a chapter-specific guide that walks you through running the code, understanding the structure, and grasping concepts unique to that stage. We believe in building on knowledge, not repeating it, so each chapter focuses on what is new while assuming you are familiar with what came before.每一章都附带其详细的 README——可以将其视为章节特定的指南,引导你运行代码、理解结构并掌握该阶段特有的概念。我们相信建立在已有知识之上,而不是重复它,因此每一章都侧重于新内容,并假设你熟悉之前的内容。

Important
While you are free to explore these chapters in any order, we strongly recommend starting with Chapter 1 and progressing sequentially. Like any good story, the earlier chapters lay crucial groundwork that makes later developments more meaningful. Jumping ahead might leave you missing important context and concepts.

Libraries and Platforms Used

Our solution is built with C# and .NET 9, complemented by a carefully curated set of libraries and platforms. We have intentionally kept external dependencies minimal - just enough to avoid reinventing wheels while keeping the focus on architecture. While using third-party tools means trading some control for productivity, we believe it is a worthwhile tradeoff for most business applications.我们的解决方案使用 C# 和 .NET 9 构建,并辅以一套精心挑选的库和平台。我们有意将外部依赖项保持在最低限度——足以避免重复造轮子,同时保持对架构的关注。虽然使用第三方工具意味着以牺牲一定的控制权来换取生产力,但我们认为对于大多数业务应用来说,这是一个值得的权衡。

Application:应用程序:

Testing:测试:

Videos 🎥视频 🎥

You can get a solid understanding of Evolutionary Architecture through these videos:你可以通过这些视频深入了解演进式架构:

Webinar from Architecture Weekly 🇬🇧

In this webinar, Maciej "MJ" Jedrzejewski gives an in-depth presentation on Evolutionary Architecture. You can watch the recorded webinar at here.在此次网络研讨会中,Maciej "MJ" Jedrzejewski 对演进式架构进行了深入的介绍。你可以在此处观看录制的研讨会。

Presentation at Programistok 2023 Conference 🇵🇱

This is a recorded presentation from the Programistok 2023 conference where Evolutionary Architecture was explained in detail. You can watch it on YouTube here.这是 Programistok 2023 大会的录制演讲,其中详细解释了演进式架构。你可以在此处 YouTube 上观看。

Evolutionary Architecture Visualized Through NDepend 🇬🇧

Explore Evolutionary Architecture visualized with NDepend, with comprehensive dependency and code analysis in the form of an interview with Kamil conducted by Ferry de Boer. Watch it on YouTube at here.探索通过 NDepend 可视化的演进式架构,包含全面的依赖项和代码分析,这是 Ferry de Boer 对 Kamil 进行的采访。在此处 YouTube 上观看。

Authors ✍️

Maciej "MJ" Jedrzejewski Kamil Baczek

Author of the book "Master Software Architecture", technology agnostic architect, and Microsoft MVP.

Book Newsletter Linkedin

.NET Engineer, software architect, and Microsoft MVP who empowers teams to build better software through solid software architecture, utilising techniques such as Event Storming, Domain Driven Design and various architecture styles and design patterns.

Blog Linkedin Github

👩‍💻👨‍💻 What Software Engeeniers Say👩‍💻👨‍💻 软件工程师的评价

👨‍💼 Chief Software Architect

Really appreciate the repository and the content you are sharing. I think it is really valuable to see the evolutionary approach in practice, and focus on simplicity and pragmatic reasoning and making decisions in software design.非常感谢这个仓库和你分享的内容。我认为在实践中看到演进式方法,并专注于简单性、务实推理以及在软件设计中做出决策,是非常有价值的。

👨‍💻 .NET Developer

Your work has been super helpful as I dive deeper into this field. Evolutionary Architecture, in particular, is incredible and has really clicked for me thanks to your examples and insights.随着我深入研究这一领域,你的工作对我帮助极大。特别是演进式架构,非常出色,多亏了你的示例和见解,我真正理解了它。

👨‍💻 .NET Developer

I was always concerned about what architecture to use on a project. Sometimes, spending time on researching what’s right affects my motivation. Your approach which focuses on creating a project with an architecture that evolves resonates perfectly with me. Your efforts in creating such a wonderful resource is greatly appreciated.我一直担心在项目中使用什么架构。有时,花时间研究什么是正确的会影响我的动力。你专注于创建一个架构会演进的项目的方法与我产生了共鸣。非常感谢你为创建如此出色的资源所做的努力。

💬 Join our Community

Connect with fellow architects and developers in our "Evolutionary Architecture" community on our Discord. Share your questions, suggestions, or feedback about our repository - we’re here to learn and improve together.在我们的 Discord 上加入“演进式架构”社区,与其他架构师和开发人员建立联系。分享你关于我们仓库的问题、建议或反馈——我们在这里共同学习和进步。

discord

⭐ Say thanks

Finding this repository helpful? Drop us a ⭐! It is a small gesture that makes a big difference in helping others discover it.觉得这个仓库有帮助吗?给我们点个 ⭐!这是一个小小的举动,却能极大地帮助他人发现它。