{"id":13445150,"url":"https://github.com/ardalis/CleanArchitecture","last_synced_at":"2025-03-20T20:31:56.604Z","repository":{"id":37406149,"uuid":"69673033","full_name":"ardalis/CleanArchitecture","owner":"ardalis","description":"Clean Architecture Solution Template: A starting point for Clean Architecture with ASP.NET Core","archived":false,"fork":false,"pushed_at":"2024-10-22T19:20:03.000Z","size":3232,"stargazers_count":16296,"open_issues_count":32,"forks_count":2810,"subscribers_count":414,"default_branch":"main","last_synced_at":"2024-10-22T21:48:54.542Z","etag":null,"topics":["architecture","clean-architecture","csharp","ddd","domain-driven-design","dotnet","hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ardalis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["ardalis"]}},"created_at":"2016-09-30T14:19:20.000Z","updated_at":"2024-10-22T20:57:30.000Z","dependencies_parsed_at":"2024-01-05T20:52:15.758Z","dependency_job_id":"1f979c02-111f-4f0a-8e10-bec8790eb5b5","html_url":"https://github.com/ardalis/CleanArchitecture","commit_stats":{"total_commits":473,"total_committers":65,"mean_commits":7.276923076923077,"dds":0.5539112050739958,"last_synced_commit":"e0eaa4c5f854f7475793e8ff80675466f6745d9b"},"previous_names":[],"tags_count":14,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ardalis%2FCleanArchitecture","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ardalis%2FCleanArchitecture/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ardalis%2FCleanArchitecture/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ardalis%2FCleanArchitecture/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ardalis","download_url":"https://codeload.github.com/ardalis/CleanArchitecture/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221807639,"owners_count":16883626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["architecture","clean-architecture","csharp","ddd","domain-driven-design","dotnet","hacktoberfest"],"created_at":"2024-07-31T05:00:24.267Z","updated_at":"2025-03-20T20:31:56.597Z","avatar_url":"https://github.com/ardalis.png","language":"C#","readme":"[![.NET Core](https://github.com/ardalis/CleanArchitecture/workflows/.NET%20Core/badge.svg)](https://github.com/ardalis/CleanArchitecture/actions)\n[![publish Ardalis.CleanArchitecture Template to nuget](https://github.com/ardalis/CleanArchitecture/actions/workflows/publish.yml/badge.svg)](https://github.com/ardalis/CleanArchitecture/actions/workflows/publish.yml)\n[![Ardalis.CleanArchitecture.Template on NuGet](https://img.shields.io/nuget/v/Ardalis.CleanArchitecture.Template?label=Ardalis.CleanArchitecture.Template)](https://www.nuget.org/packages/Ardalis.CleanArchitecture.Template/)\n\n\u003ca href=\"https://twitter.com/intent/follow?screen_name=ardalis\"\u003e\n    \u003cimg src=\"https://img.shields.io/twitter/follow/ardalis.svg?label=Follow%20@ardalis\" alt=\"Follow @ardalis\" /\u003e\n\u003c/a\u003e \u0026nbsp; \u003ca href=\"https://twitter.com/intent/follow?screen_name=nimblepros\"\u003e\n    \u003cimg src=\"https://img.shields.io/twitter/follow/nimblepros.svg?label=Follow%20@nimblepros\" alt=\"Follow @nimblepros\" /\u003e\n\u003c/a\u003e\n\n# Clean Architecture\n\nA starting point for Clean Architecture with ASP.NET Core. [Clean Architecture](https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html) is just the latest in a series of names for the same loosely-coupled, dependency-inverted architecture. You will also find it named [hexagonal](http://alistair.cockburn.us/Hexagonal+architecture), [ports-and-adapters](http://www.dossier-andreas.net/software_architecture/ports_and_adapters.html), or [onion architecture](http://jeffreypalermo.com/blog/the-onion-architecture-part-1/).\n\nLearn more about Clean Architecture and this template in [NimblePros' Introducing Clean Architecture course](https://academy.nimblepros.com/p/learn-clean-architecture). Use code ARDALIS to save 20%.\n\nThis architecture is used in the [DDD Fundamentals course](https://www.pluralsight.com/courses/fundamentals-domain-driven-design) by [Steve Smith](https://ardalis.com) and [Julie Lerman](https://thedatafarm.com/).\n\n:school: Contact Steve's company, [NimblePros](https://nimblepros.com/), for Clean Architecture or DDD training and/or implementation assistance for your team.\n\n## Take the Course!\n\n[Learn about how to implement Clean Architecture](https://academy.nimblepros.com/p/intro-to-clean-architecture) from [NimblePros](https://nimblepros.com) trainers [Sarah \"sadukie\" Dutkiewicz](https://blog.nimblepros.com/author/sadukie/) and [Steve \"ardalis\" Smith](https://blog.nimblepros.com/author/ardalis/).\n\n## Table Of Contents\n\n- [Clean Architecture](#clean-architecture)\n  - [Troubleshooting Chrome Errors](#troubleshooting-chrome-errors)\n  - [Table Of Contents](#table-of-contents)\n  - [Give a Star! :star:](#give-a-star-star)\n  - [Versions](#versions)\n  - [Learn More](#learn-more)\n- [Getting Started](#getting-started)\n  - [Using the dotnet CLI template](#using-the-dotnet-cli-template)\n  - [What about Controllers and Razor Pages?](#what-about-controllers-and-razor-pages)\n    - [Add Ardalis.ApiEndpoints](#add-ardalisapiendpoints)\n    - [Add Controllers](#add-controllers)\n    - [Add Razor Pages](#add-razor-pages)\n  - [Using the GitHub Repository](#using-the-github-repository)\n  - [Running Migrations](#running-migrations)\n- [Goals](#goals)\n  - [History and Shameless Plug Section](#history-and-shameless-plug-section)\n- [Design Decisions and Dependencies](#design-decisions-and-dependencies)\n  - [Where To Validate](#where-to-validate)\n  - [The Core Project](#the-core-project)\n  - [The Use Cases Project](#the-use-cases-project)\n  - [The Infrastructure Project](#the-infrastructure-project)\n  - [The Web Project](#the-web-project)\n  - [The SharedKernel Project](#the-sharedkernel-project)\n  - [The Test Projects](#the-test-projects)\n- [Patterns Used](#patterns-used)\n  - [Domain Events](#domain-events)\n  - [Related Projects](#related-projects)\n\n## Give a Star! :star:\n\nIf you like or are using this project to learn or start your solution, please give it a star. Thanks!\n\nOr if you're feeling really generous, we now support GitHub sponsorships - see the button above.\n\n## Sponsors\n\nI'm please to announce that [Amazon AWS's FOSS fund](https://github.com/aws/dotnet-foss) has chosen to award a 12-month sponsorship to this project. Thank you, and thanks to all of my other past and current sponsors!\n\n## Troubleshooting Chrome Errors\n\nBy default the site uses HTTPS and expects you to have a self-signed developer certificate for localhost use. If you get an error with Chrome [see this answer](https://stackoverflow.com/a/31900210/13729) for mitigation instructions.\n\n## Versions\n\nThe main branch is now using **.NET 9**. This corresponds with NuGet package version 10.x. Previous versions are available - see our [Releases](https://github.com/ardalis/CleanArchitecture/releases).\n\n## Learn More\n\n- [Live Stream Recordings Working on Clean Architecture](https://www.youtube.com/c/Ardalis/search?query=clean%20architecture)\n- [DotNetRocks Podcast Discussion with Steve \"ardalis\" Smith](https://player.fm/series/net-rocks/clean-architecture-with-steve-smith)\n- [Fritz and Friends Streaming Discussion with Steve \"ardalis\" Smith](https://www.youtube.com/watch?v=k8cZUW4MS3I)\n\n# Getting Started\n\nTo use this template, there are a few options:\n\n- Install using `dotnet new` (recommended)\n- Download this Repository (and modify as needed)\n\n## Using the dotnet CLI template\n\nFirst, install the template from [NuGet (https://www.nuget.org/packages/Ardalis.CleanArchitecture.Template/)](https://www.nuget.org/packages/Ardalis.CleanArchitecture.Template/):\n\n```powershell\ndotnet new install Ardalis.CleanArchitecture.Template\n```\n\nYou can see available options by running the command with the `-?` option:\n\n```powershell\ndotnet new clean-arch -?\nASP.NET Clean Architecture Solution (C#)\nAuthor: Steve Smith @ardalis, Erik Dahl\n\nUsage:\n  dotnet new clean-arch [options] [template options]\n\nOptions:\n  -n, --name \u003cname\u003e       The name for the output being created. If no name is specified, the name of the output\n                          directory is used.\n  -o, --output \u003coutput\u003e   Location to place the generated output.\n  --dry-run               Displays a summary of what would happen if the given command line were run if it would result\n                          in a template creation.\n  --force                 Forces content to be generated even if it would change existing files.\n  --no-update-check       Disables checking for the template package updates when instantiating a template.\n  --project \u003cproject\u003e     The project that should be used for context evaluation.\n  -lang, --language \u003cC#\u003e  Specifies the template language to instantiate.\n  --type \u003cproject\u003e        Specifies the template type to instantiate.\n\nTemplate options:\n  -as, --aspire  Include .NET Aspire.\n                 Type: bool\n                 Default: false\n```\n\nYou should see the template in the list of templates from `dotnet new list` after this installs successfully. Look for \"ASP.NET Clean Architecture Solution\" with Short Name of \"clean-arch\".\n\nNavigate to the parent directory in which you'd like the solution's folder to be created.\n\nRun this command to create the solution structure in a subfolder name `Your.ProjectName`:\n\n```\ndotnet new clean-arch -o Your.ProjectName\n```\n\nThe `Your.ProjectName` directory and solution file will be created, and inside that will be all of your new solution contents, properly namespaced and ready to run/test!\n\nExample:\n![powershell screenshot showing steps](https://user-images.githubusercontent.com/782127/101661723-9fd28e80-3a16-11eb-8be4-f9195d825ad6.png)\n\nThanks [@dahlsailrunner](https://github.com/dahlsailrunner) for your help getting this working!\n\n**Known Issues**: \n\n- Don't include hyphens in the name. See [#201](https://github.com/ardalis/CleanArchitecture/issues/201).\n- Don't use 'Ardalis' as your namespace (conflicts with dependencies).\n\n## What about Controllers and Razor Pages?\n\nAs of version 9, this solution template only includes support for API Endpoints using the FastEndpoints library. If you want to use my ApiEndpoints library, Razor Pages, and/or Controllers you can use the last template that included them, [version 7.1](https://www.nuget.org/packages/Ardalis.CleanArchitecture.Template/7.1.0). Alternately, they're easily added to this template after installation.\n\n### Add Ardalis.ApiEndpoints\n\nTo use [Ardalis.ApiEndpoints](https://www.nuget.org/packages/Ardalis.ApiEndpoints) instead of (or in addition to) [FastEndpoints](https://fast-endpoints.com/), just add the reference and use the base classes from the documentation.\n\n```powershell\ndotnet add package Ardalis.ApiEndpoints\n```\n\n### Add Controllers\n\nYou'll need to add support for controllers to the Program.cs file. You need:\n\n```csharp\nbuilder.Services.AddControllers(); // ControllersWithView if you need Views\n\n// and\n\napp.MapControllers();\n```\n\nOnce these are in place, you should be able to create a Controllers folder and (optionally) a Views folder and everything should work as expected. Personally I find Razor Pages to be much better than Controllers and Views so if you haven't fully investigated Razor Pages you might want to do so right about now before you choose Views.\n\n### Add Razor Pages\n\nYou'll need to add support for Razor Pages to the Program.cs file. You need:\n\n```csharp\nbuilder.Services.AddRazorPages();\n\n// and\n\napp.MapRazorPages();\n```\n\nThen you just add a Pages folder in the root of the project and go from there.\n\n## Using the GitHub Repository\n\nTo get started based on this repository, you need to get a copy locally. You have three options: fork, clone, or download. Most of the time, you probably just want to download.\n\nYou should **download the repository**, unblock the zip file, and extract it to a new folder if you just want to play with the project or you wish to use it as the starting point for an application.\n\nYou should **fork this repository** only if you plan on submitting a pull request. Or if you'd like to keep a copy of a snapshot of the repository in your own GitHub account.\n\nYou should **clone this repository** if you're one of the contributors and you have commit access to it. Otherwise you probably want one of the other options.\n\n## Running Migrations\n\nYou shouldn't need to do this to use this template, but if you want migrations set up properly in the Infrastructure project, you need to specify that project name when you run the migrations command.\n\nIn Visual Studio, open the Package Manager Console, and run `Add-Migration InitialMigrationName -StartupProject Your.ProjectName.Web -Context AppDbContext -Project Your.ProjectName.Infrastructure`.\n\nIn a terminal with the CLI, the command is similar. Run this from the Web project directory:\n\n```powershell\ndotnet ef migrations add MIGRATIONNAME -c AppDbContext -p ../Your.ProjectName.Infrastructure/Your.ProjectName.Infrastructure.csproj -s Your.ProjectName.Web.csproj -o Data/Migrations\n```\n\nTo use SqlServer, change `options.UseSqlite(connectionString));` to `options.UseSqlServer(connectionString));` in the `Your.ProjectName.Infrastructure.StartupSetup` file. Also remember to replace the `SqliteConnection` with `DefaultConnection` in the `Your.ProjectName.Web.Program` file, which points to your Database Server.\n\nTo update the database use this command from the Web project folder (replace `Clean.Architecture` with your project's name):\n\n```powershell\ndotnet ef database update -c AppDbContext -p ../Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj -s Clean.Architecture.Web.csproj\n```\n\n# Goals\n\nThe goal of this repository is to provide a basic solution structure that can be used to build Domain-Driven Design (DDD)-based or simply well-factored, SOLID applications using .NET Core. Learn more about these topics here:\n\n- [SOLID Principles for C# Developers](https://www.pluralsight.com/courses/csharp-solid-principles)\n- [Domain-Driven Design Fundamentals](https://www.pluralsight.com/courses/fundamentals-domain-driven-design)\n- [Refactoring to SOLID C# Code](https://www.pluralsight.com/courses/refactoring-solid-c-sharp-code)\n\nIf you're used to building applications as single-project or as a set of projects that follow the traditional UI -\u003e Business Layer -\u003e Data Access Layer \"N-Tier\" architecture, I recommend you check out these two courses (ideally before DDD Fundamentals):\n\n- [Creating N-Tier Applications in C#, Part 1](https://www.pluralsight.com/courses/n-tier-apps-part1)\n- [Creating N-Tier Applications in C#, Part 2](https://www.pluralsight.com/courses/n-tier-csharp-part2)\n\nSteve Smith also maintains Microsoft's reference application, eShopOnWeb, and its associated free eBook. Check them out here:\n\n- [eShopOnWeb on GitHub](https://github.com/nimblepros/eShopOnWeb) (now supported by [NimblePros](https://nimblepros.com))\n- [Architecting Modern Web Applications with ASP.NET Core and Microsoft Azure](https://aka.ms/webappebook) (eBook)\n\nNote that the goal of this project and repository is **not** to provide a sample or reference application. It's meant to just be a template, but with enough pieces in place to show you where things belong as you set up your actual solution. Instead of useless \"Class1.cs\" there are a few real classes in place. Delete them as soon as you understand why they're there and where you should put your own, similar files. There *is* a sample application in the `/sample` folder, if you're looking for that.\n\n## History and Shameless Plug Section\n\nI've used this starter kit to teach the basics of ASP.NET Core using Domain-Driven Design concepts and patterns for some time now (starting when ASP.NET Core was still in pre-release). Typically I teach a one- or two-day hands-on workshop ahead of events like DevIntersection, or private on-site workshops for companies looking to bring their teams up to speed with the latest development technologies and techniques. Feel free to [contact me](https://nimblepros.com/) if you'd like information about upcoming workshops.\n\n# Design Decisions and Dependencies\n\nThe goal of this solution template is to provide a fairly bare-bones starter kit for new projects. It does not include every possible framework, tool, or feature that a particular enterprise application might benefit from. Its choices of technology for things like data access are rooted in what is the most common, accessible technology for most business software developers using Microsoft's technology stack. It doesn't (currently) include extensive support for things like logging, monitoring, or analytics, though these can all be added easily. Below is a list of the technology dependencies it includes, and why they were chosen. Most of these can easily be swapped out for your technology of choice, since the nature of this architecture is to support modularity and encapsulation.\n\n## Where To Validate\n\nValidation of user input is a requirement of all software applications. The question is, where does it make sense to implement it in a concise and elegant manner? This solution template includes 4 separate projects, each of which might be responsible for performing validation as well as enforcing business invariants (which, given validation should already have occurred, are usually modeled as exceptions).\n\n- [When to Validate and When to Throw Exceptions](https://www.youtube.com/watch?v=dpPcnAT7n7M)\n\nThe domain model itself should generally rely on object-oriented design to ensure it is always in a consistent state. It leverages encapsulation and limits public state mutation access to achieve this, and it assumes that any arguments passed to it have already been validated, so null or other improper values yield exceptions, not validation results, in most cases.\n\nThe use cases / application project includes the set of all commands and queries the system supports. It's frequently responsible for validating its own command and query objects. This is most easily done using a [chain of responsibility pattern](https://deviq.com/design-patterns/chain-of-responsibility-pattern) via MediatR behaviors or some other pipeline.\n\nThe Web project includes all API endpoints, which include their own request and response types, following the [REPR pattern](https://deviq.com/design-patterns/repr-design-pattern). The FastEndpoints library includes built-in support for validation using FluentValidation on the request types. This is a natural place to perform input validation as well.\n\nHaving validation occur both within the API endpoints and then again at the use case level may be considered redundant. There are tradeoffs to adding essentially the same validation in two places, one for API requests and another for messages sent to Use Case handlers. Following defensive coding, it often makes sense to add validation in both places, as the overhead is minimal and the peace of mind of mind and greater application robustness is often worth it.\n\n## The Core Project\n\nThe Core project is the center of the Clean Architecture design, and all other project dependencies should point toward it. As such, it has very few external dependencies. The Core project should include the Domain Model including things like:\n\n- Entities\n- Aggregates\n- Value Objects\n- Domain Events\n- Domain Event Handlers\n- Domain Services\n- Specifications\n- Interfaces\n- DTOs (sometimes)\n\nYou can learn more about these patterns and how to apply them here:\n\n- [DDD Fundamentals](https://www.pluralsight.com/courses/fundamentals-domain-driven-design)\n- [DDD Concepts](https://deviq.com/domain-driven-design/ddd-overview)\n\n## The Use Cases Project\n\nAn optional project, I've included it because many folks were demanding it and it's easier to remove than to add later. This is also often referred to as the *Application* or *Application Services* layer. The Use Cases project is organized following CQRS into Commands and Queries (I considered having folders for `Commands` and `Queries` but felt it added little - the folders per actual *command* or *query* is sufficient without extra nesting). Commands mutate the domain model and thus should always use Repository abstractions for their data access (Repositories are how one fetches and persists domain model types). Queries are readonly, and thus **do not need to use the repository pattern**, but instead can use whatever query service or approach is most convenient.\n\nSince the Use Cases project is set up to depend on Core and does not depend on Infrastructure, there will still need to be abstractions defined for its data access. And it *can* use things like specifications, which can sometimes help encapsulate query logic as well as result type mapping. But it doesn't *have* to use repository/specification - it can just issue a SQL query or call a stored procedure if that's the most efficient way to get the data.\n\nAlthough this is an optional project to include (without it, your API endpoints would just work directly with the domain model or query services), it does provide a nice UI-ignorant place to add automated tests, and lends itself toward applying policies for cross-cutting concerns using a Chain of Responsibility pattern around the message handlers (for things like validation, caching, auth, logging, timing, etc.). The template includes an example of this for logging, which is located in the [SharedKernel NuGet package](https://github.com/ardalis/Ardalis.SharedKernel/blob/main/src/Ardalis.SharedKernel/LoggingBehavior.cs).\n\n## The Infrastructure Project\n\nMost of your application's dependencies on external resources should be implemented in classes defined in the Infrastructure project. These classes should implement interfaces defined in Core. If you have a very large project with many dependencies, it may make sense to have multiple Infrastructure projects (e.g. Infrastructure.Data), but for most projects one Infrastructure project with folders works fine. The template includes data access and domain event implementations, but you would also add things like email providers, file access, web api clients, etc. to this project so they're not adding coupling to your Core or UI projects.\n\n## The Web Project\n\nThe entry point of the application is the ASP.NET Core web project (or possibly the AspireHost project, which in turn loads the Web project). This is actually a console application, with a `public static void Main` method in `Program.cs`. It leverages FastEndpoints and the REPR pattern to organize its API endpoints.\n\n## The SharedKernel Package\n\nA [Shared Kernel](https://deviq.com/domain-driven-design/shared-kernel) is used to share common elements between bounded contexts. It's a DDD term but many organizations leverage \"common\" projects or packages for things that are useful to share between several applications.\n\nI recommend creating a separate SharedKernel project and solution if you will require sharing code between multiple [bounded contexts](https://ardalis.com/encapsulation-boundaries-large-and-small/) (see [DDD Fundamentals](https://www.pluralsight.com/courses/domain-driven-design-fundamentals)). I further recommend this be published as a NuGet package (most likely privately within your organization) and referenced as a NuGet dependency by those projects that require it.\n\nPreviously a project for SharedKernel was included in this project. However, for the above reasons I've made it a separate package, [Ardalis.SharedKernel](https://github.com/ardalis/Ardalis.SharedKernel), which **you should replace with your own when you use this template**.\n\nIf you want to see another [example of a SharedKernel package, the one I use in my updated Pluralsight DDD course is on NuGet here](https://www.nuget.org/packages/PluralsightDdd.SharedKernel/).\n\n## The Test Projects\n\nTest projects could be organized based on the kind of test (unit, functional, integration, performance, etc.) or by the project they are testing (Core, Infrastructure, Web), or both. For this simple starter kit, the test projects are organized based on the kind of test, with unit, functional and integration test projects existing in this solution. Functional tests are a special kind of [integration test](https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-8.0) that perform [subcutaneous testing](https://martinfowler.com/bliki/SubcutaneousTest.html) of the APIs of the Web project, without actually hosting a real website or going over the network. I've created a bunch of [test helpers](https://github.com/ardalis/HttpClientTestExtensions) to make these kinds of tests shorter and easier to maintain.\n\n# Patterns Used\n\nThis solution template has code built in to support a few common patterns, especially Domain-Driven Design patterns. Here is a brief overview of how a few of them work.\n\n## Domain Events\n\nDomain events are a great pattern for decoupling a trigger for an operation from its implementation. This is especially useful from within domain entities since the handlers of the events can have dependencies while the entities themselves typically do not. In the sample, you can see this in action with the `ToDoItem.MarkComplete()` method. The following sequence diagram demonstrates how the event and its handler are used when an item is marked complete through a web API endpoint.\n\n![Domain Event Sequence Diagram](https://user-images.githubusercontent.com/782127/75702680-216ce300-5c73-11ea-9187-ec656192ad3b.png)\n\n## Related Projects\n\n- [ApiEndpoints](https://github.com/ardalis/apiendpoints)\n- [GuardClauses](https://github.com/ardalis/guardclauses)\n- [HttpClientTestExtensions](https://github.com/ardalis/HttpClientTestExtensions)\n- [Result](https://github.com/ardalis/result)\n- [SharedKernel](https://github.com/ardalis/Ardalis.SharedKernel)\n- [SmartEnum](https://github.com/ardalis/SmartEnum)\n- [Specification](https://github.com/ardalis/specification)\n- [FastEndpoints](https://fast-endpoints.com/)\n\n## Presentations and Videos on Clean Architecture\n\n- [What's New in Clean Architecture Template 9.1](https://www.youtube.com/watch?v=EJIgjL41em4)\n- [The REPR Pattern and Clean Architecture](https://www.youtube.com/watch?v=-AJcEJPwagQ)\n- [Clean Architecture with ASP.NET Core 8](https://www.youtube.com/watch?v=yF9SwL0p0Y0)\n- [Getting Started with Clean Architecture and .NET 8 (webinar)](https://www.youtube.com/watch?v=IsmyqNrfQQw)\n\n","funding_links":["https://github.com/sponsors/ardalis"],"categories":["Frameworks, Libraries and Tools","C\\#","C#","C# #","Templates","Starter Kits","其他","Repos","hacktoberfest","框架, 库和工具"],"sub_categories":["Application Templates","Templates","网络服务_其他","应用程序模板"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fardalis%2FCleanArchitecture","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fardalis%2FCleanArchitecture","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fardalis%2FCleanArchitecture/lists"}