{"id":23552326,"url":"https://github.com/michaldivis/unicorn-valley","last_synced_at":"2025-05-15T17:14:14.368Z","repository":{"id":115181508,"uuid":"535617869","full_name":"michaldivis/unicorn-valley","owner":"michaldivis","description":"C# demo app that uses as many of the \"buzzword\" design patterns as possible","archived":false,"fork":false,"pushed_at":"2022-10-10T09:57:13.000Z","size":543,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-15T17:13:52.194Z","etag":null,"topics":["clean-architecture","cqrs","ddd","domain-events","problem-details","repository-pattern","unit-of-work","value-object"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/michaldivis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"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}},"created_at":"2022-09-12T10:35:54.000Z","updated_at":"2022-10-10T10:00:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"2f8eeb61-5508-4ca6-810b-117cfb44a367","html_url":"https://github.com/michaldivis/unicorn-valley","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaldivis%2Funicorn-valley","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaldivis%2Funicorn-valley/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaldivis%2Funicorn-valley/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaldivis%2Funicorn-valley/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/michaldivis","download_url":"https://codeload.github.com/michaldivis/unicorn-valley/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254384985,"owners_count":22062422,"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":["clean-architecture","cqrs","ddd","domain-events","problem-details","repository-pattern","unit-of-work","value-object"],"created_at":"2024-12-26T11:10:21.710Z","updated_at":"2025-05-15T17:14:14.362Z","avatar_url":"https://github.com/michaldivis.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿\u003cimg src=\"assets/icon.png\" width=\"200\"\u003e\n\n# Unicorn Valley\n\nWhat is this?\n\u003e What would happen if you used every \"buzzword\" design pattern in a single project?\\\n\u003e That's what this is...\n\nThis is a solution an example of a ASP.NET Core Minimal API and a console client following the principles of Clean Architecture, Domain Driver Design, an a few other principles and patterns.\n\nI've made it a challenge to use as many of the \"buzzword\" patterns as possible. As a result, the usage of some of these might be considered an overkill and unnecesary. But here we are...\n\n## Used principles \u0026 patterns\n\n- Clean Architecture\n- [Domain Driver Design](https://en.wikipedia.org/wiki/Domain-driven_design)\n- [CQRS](https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs) using [MediatR](https://github.com/jbogard/MediatR)\n- Command \u0026 Query validation using [\u003cimg src=\"assets/icons/fluent-validation.png\" style=\"vertical-align:middle\" height=30\u003e](https://docs.fluentvalidation.net/en/latest/)\n- [REPR](https://deviq.com/design-patterns/repr-design-pattern) (Request-Endpoint-Response) using [\u003cimg src=\"assets/icons/fast-endpoints.svg\" style=\"vertical-align:middle\" height=30\u003e](https://fast-endpoints.com/) \n- [Domain Events](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/domain-events-design-implementation)\n- Result objects (instead of throwing exceptions) using [\u003cimg src=\"assets/icons/fluentresults.png\" style=\"vertical-align:middle\" height=30\u003e FluentResults](https://github.com/altmann/FluentResults)\n- [Repository pattern](https://dotnettutorials.net/lesson/repository-design-pattern-csharp/#:~:text=What%20is%20the%20Repository%20Design,for%20accessing%20the%20domain%20objects.\u0026text=In%20the%20above%20design%2C%20now,Framework%20data%20context%20class%20directly.)\n- [Unit of work](https://dotnettutorials.net/lesson/unit-of-work-csharp-mvc/#:~:text=The%20Unit%20of%20Work%20pattern,or%20fail%20as%20one%20unit.) pattern\n- [Value objects](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/implement-value-objects) to represent things like a username or an e-mail address using [ValueOf](https://github.com/mcintyre321/ValueOf)\n- using the [Problem details](https://www.rfc-editor.org/rfc/rfc7807) standard for API error responses\n- auto-generating API client code using [\u003cimg src=\"assets/icons/refit.png\" style=\"vertical-align:middle\" height=30\u003e Refit](https://github.com/reactiveui/refit)\n\n## Project structure\n\n**Core**\n- **Domain**: entities, enums, interfaces, domain errors, value objects, types and logic specific to the domain layer\n- **Application**: This layer contains all application logic. It is dependent on the domain layer, but has no dependencies on any other layer or project. This layer only contains commands, queries, and their handlers.\n- **Infrastructure**: This layer contains classes for accessing external resources such as file systems, web services, smtp, and so on. In this particular case, it contains the EF Core db context and repository implementations.\n- **WebAPI**: This layer is a REST API. This layer depends on both the Application and Infrastructure layers, however, the dependency on Infrastructure is only to support dependency injection. Therefore only Program.cs should reference Infrastructure.\n\n**Client**\n- **ApiClient**: API client library. Contains API contracts and the Refit API interface. This library can be used by any client app (console/WPF)\n- **ConsoleClient**: A console client. Uses the *ApiClient* library to call the API.\n\n## DDD Entities \u0026 Aggregate root\nThis project has a rich domain model. The domain models are responsible for all (or most of) the domain logic.\n\nExample: [Meeting.cs](src/Domain/Entities/Meeting.cs)\n\n## CQRS \u0026 validation\nThe Application layer contains commands and queries. Both commands and queries can be validated using [FluentValidation](https://docs.fluentvalidation.net/en/latest/).\n\nExample command: [CreateUserCommand.cs](src/Application/Users/Commands/CreateUserCommand.cs)\\\nExample command validator: [CreateUserCommandValidator.cs](src/Application/Users/Commands/CreateUserCommandValidator.cs)\\\nExample command handler: [CreateUserCommandHandler.cs](src/Application/Users/Commands/CreateUserCommandHandler.cs)\n\n## REPR using Fast Endpoints\nThe minimal API is implemented using the [Fast Endpoints](https://fast-endpoints.com/) library. There's one file per endpoint. \n\nExample: [Create User Endpoint.cs](src/WebAPI/Endpoints/Users/Create.cs).\n\n## Result objects\nI'm using result objects to return complex results (success/failure + success/error messages).\n\nA domain method, such a the [Create User Method](src/Domain/Entities/User.cs). will return a `Result\u003cUser\u003e`. This result object will either contain a valid `User` instance of an error message.\n\nThe result object is (in case of an error) later converted into an API problem details response [here](src/WebAPI/Utils/ResponseUtils.cs).\n\nThe same result object is also logged (to a rich, structured log) [here](src/WebAPI/Services/ResultHandler.cs).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaldivis%2Funicorn-valley","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichaldivis%2Funicorn-valley","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaldivis%2Funicorn-valley/lists"}