百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
C

clean-architecture

> 编程语言
开源

适用于 .NET 应用程序的终极清晰架构模板

1.9K stars0 点赞0 次浏览
访问官网GitHub

工具介绍

适用于 .NET 应用程序的终极清晰架构模板

dotnet new install Amantinband.CleanArchitecture.Template

dotnet new clean-arch -o CleanArchitecture
  • ️Important notice ⚠️
  • Give it a star ⭐
  • Domain Overview
    • Basic Subscription
    • Pro Subscription
  • Use Cases / Features
    • Subscriptions
    • Reminders
  • Getting Started
    • YouTube Tutorial
    • Install the template or clone the project
    • Run the service using Docker or the .NET CLI
    • Generate a token
    • Create a subscription
    • Create a reminder
  • Folder Structure
  • Authorization
    • Authorization Types
      • Role-Based Authorization
      • Permission-Based Authorization
      • Policy-Based Authorization
    • Mixing Authorization Types
  • Testing
    • Test Types
      • Domain Layer Unit Tests
      • Application Layer Unit Tests
      • Application Layer Subcutaneous Tests
      • Presentation Layer Integration Tests
  • Fun features
    • Domain Events & Eventual Consistency
      • Eventual Consistency Mechanism
    • Background service for sending email reminders
      • Configure Email Settings
      • Configure Email Settings Manually
      • Configure Email Settings via User Secrets
  • Contribution
  • Credits
  • License

️Important notice ⚠️

This template is still under construction .

Check out my comprehensive course on Dometrain where I cover everything you need to know when building production applications structured following clean architecture. Use the exclusive coupon code GITHUB to get 5% off (btw this is the only promo code for a discount on the bundle, which is already 20% off).

Give it a star ⭐

Loving it? Show your support by giving this project a star!

Domain Overview

This is a simple reminder application. It allows users to create and manage their reminders.

To create reminders, a user must have an active subscription.

Basic Subscription

Users with a basic subscription can create up to 3 daily reminders.

Pro Subscription

Users with a pro subscription do not have a daily limit on the number of reminders.

Use Cases / Features

Subscriptions

  1. Create Subscription
  2. Get Subscription
  3. Cancel Subscription

Reminders

  1. Set Reminder
  2. Get Reminder
  3. Delete Reminder
  4. Dismiss Reminder
  5. List Reminders

Getting Started

YouTube Tutorial

Install the template or clone the project

dotnet new install Amantinband.CleanArchitecture.Template

dotnet new clean-arch -o CleanArchitecture

or

git clone https://github.com/amantinband/clean-architecture

Run the service using Docker or the .NET CLI

docker compose up

or

dotnet run --project src/CleanArchitecture.Api

Generate a token

Navigate to requests/Tokens/GenerateToken.http and generate a token.

Note: Since most systems use an external identity provider, this project uses a simple token generator endpoint that generates a token based on the details you provide. This is a simple way to generate a token for testing purposes and is closer to how your system will likely be designed when using an external identity provider.

POST {{host}}/tokens/generate
Content-Type: application/json
{
    "Id": "bae93bf5-9e3c-47b3-aace-3034653b6bb2",
    "FirstName": "Amichai",
    "LastName": "Mantinband",
    "Email": "[email protected]",
    "Permissions": [
        "set:reminder",
        "get:reminder",
        "dismiss:reminder",
        "delete:reminder",
        "create:subscription",
        "delete:subscription",
        "get:subscription"
    ],
    "Roles": [
        "Admin"
    ]
}

NOTE: Replacing http file variables ({{variableName}})

Option 1 (recommended) - Using the REST Client extension for VS Code

Use the REST Client extension for VS Code + update the values under .vscode/settings.json. This will update the value for all http files.

…

Options 2 - Defining the variables in the http file itself

Define the variables in the http file itself. This will only update the value for the current http file.

@host = http://localhost:5001

POST {{host}}/tokens/generate

Option 3 - Manually

Replace the variables manually.

POST {{host}}/tokens/generate
POST http://localhost:5001/tokens/generate

Create a subscription

POST {{host}}/users/{{userId}}/subscriptions
Content-Type: application/json
Authorization: Bearer {{token}}
{
    "SubscriptionType": "Basic"
}

Create a reminder

POST {{host}}/users/{{userId}}/subscriptions/{{subscriptionId}}/reminders
Content-Type: application/json
Authorization: Bearer {{token}}
{
    "text": "let's do it",
    "dateTime": "2025-2-26"
}

Folder Structure

You can use the this figma community file to explore or create your own folder structure respresentation.

Authorization

This project puts an emphasis on complex authorization scenarios and supports role-based, permission-based and policy-based authorization.

Authorization Types

Role-Based Authorization

To apply role based authorization, use the Authorize attribute with the Roles parameter and implement the IAuthorizeableRequest interface.

For example:

[Authorize(Roles = "Admin")]
public record CancelSubscriptionCommand(Guid UserId, Guid SubscriptionId) : IAuthorizeableRequest<ErrorOr<Success>>;

Will only allow users with the Admin role to cancel subscriptions.

Permission-Based Authorization

To apply permission based authorization, use the Authorize attribute with the Permissions parameter and implement the IAuthorizeableRequest interface.

For example:

[Authorize(Permissions = "get:reminder")]
public record GetReminderQuery(Guid UserId, Guid SubscriptionId, Guid ReminderId) : IAuthorizeableRequest<ErrorOr<Reminder>>;

Will only allow users with the get:reminder permission to get a subscription.

Policy-Based Authorization

To apply policy based authorization, use the Authorize attribute with the Policy parameter and implement the IAuthorizeableRequest interface.

For example:

[Authorize(Policies = "SelfOrAdmin")]
public record GetReminderQuery(Guid UserId, Guid SubscriptionId, Guid ReminderId) : IAuthorizeableRequest<ErrorOr<Reminder>>;

Will only allow users who pass the SelfOrAdmin policy to get a subscription.

Each policy is implemented as a simple method in the PolicyEnforcer class.

The policy "SelfOrAdmin" for example, can be implemented as follows:

…

Mixing Authorization Types

You can mix and match authorization types to create complex authorization scenarios.

For example:

[Authorize(Permissions = "get:reminder,list:reminder", Policies = "SelfOrAdmin", Roles = "ReminderManager")]
public record ListRemindersQuery(Guid UserId, Guid SubscriptionId, Guid ReminderId) : IAuthorizeableRequest<ErrorOr<Reminder>>;

Will only allow users with the get:reminder and list:reminder permission, and who pass the SelfOrAdmin policy, and who have the ReminderManager role to list reminders.

Another option, is specifying the Authorize attribute multiple times:

[Authorize(Permissions = "get:reminder")]
[Authorize(Permissions = "list:reminder")]
[Authorize(Policies = "SelfOrAdmin")]
[Authorize(Roles = "ReminderManager")]
public record ListRemindersQuery(Guid UserId, Guid SubscriptionId, Guid ReminderId) : IAuthorizeableRequest<ErrorOr<Reminder>>;

Testing

This project puts an emphasis on testability and comes with a comprehensive test suite.

Test Types

Domain Layer Unit Tests

The domain layer is tested using unit tests. By the bare minimum, each domain entity should have a test that verifies its invariants.

Application Layer Unit Tests

The application layer is tested using both unit tests and subcutaneous tests.

Since each one of the application layer use cases has its corresponding subcutaneous tests, the unit tests are used to test the application layer standalone components, such as the ValidationBehavior and the AuthorizationBehavior.

Application Layer Subcutaneous Tests

Subcutaneous tests are tests that operate right under the presentation layer. These tests are responsible for testing the core logic of our application, which is the application layer and the domain layer.

The reason there are so many of these tests, is because each one of the application layer use cases has its corresponding subcutaneous tests.

This allows us to test the application layer and the domain layer based on the actual expected usage, giving us the confidence that our application works as expected and that the system cannot be manipulated in a way we don't allow.

I recommend spending more effort on these tests than the other tests, since they aren't too expensive to write, and the value they provide is huge.

Presentation Layer Integration Tests

The api layer is tested using integration tests. This is where we want to cover the entire system, including the database, external dependencies and the presentation layer.

Unlike the subcutaneous tests, the focus of these tests is to ensure the integration between the various components of our system and other systems.

Fun features

Domain Events & Eventual Consistency

Note: Eventual consistency and the domain events pattern add a layer of complexity. If you don't need it, don't use it. If you need it, make sure your system is designed properly and that you have the right tools to manage failures.

The domain is designed so each use case which manipulates data, updates a single domain object in a single transaction.

For example, when a user cancels a subscription, the only change that happens atomically is the subscription is marked as canceled:

public ErrorOr<Success> CancelSubscription(Guid subscriptionId)
{
    if (subscriptionId != Subscription.Id)
    {
        return Error.NotFound("Subscription not found");
    }

    Subscription = Subscription.Canceled;

    _domainEvents.Add(new SubscriptionCanceledEvent(this, subscriptionId));

    return Result.Success;
}

Then, in an eventual consistency manner, the system will update all the relevant data. Which includes:

  1. Deleting the subscription from the database and marking all reminders as deleted (Subscriptions/Events/SubscriptionDeletedEventHandler.cs])
  2. Deleting all the reminders marked as deleted from the databa

GitHub Issues· 0 开放

在 GitHub 查看全部

暂无开放 Issues,或尚未同步最近议题。

核心特点

  • •️Important notice ⚠️
  • •Give it a star ⭐
  • •Domain Overview
  • •Basic Subscription
  • •Pro Subscription
  • •Use Cases / Features
  • •Subscriptions
  • •Reminders
  • •Getting Started
  • •YouTube Tutorial

> 标签

C#asp-net-coreclean-architecturedotnetdotnet-core

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言