Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Full-stack .Net 9 Clean Architecture (Microservices, Modular Monolith, Monolith), Blazor, Angular 20, React 19, Vue 3.5, BFF with YARP, NextJs 15, Domain-Driven Design, CQRS, SOLID, Asp.Net Core Identity Custom Storage, OpenID Connect, EF Core, OpenTelemetry, SignalR, Background Services, Health Checks, Rate Limiting, Clouds (Azure, AWS, GCP), ..

License

NotificationsYou must be signed in to change notification settings

phongnguyend/Practical.CleanArchitecture

Repository files navigation

⚠️Warning

The code samples contain multiple ways and patterns to do things and not always be considered best practices or recommended for all situations.

alt text

(open on draw.io)

Hexagonal Architecture

alt text

(open on draw.io)

Onion Architecture

alt text

(open on draw.io)

The Clean Architecture

alt text

(open on draw.io)

Classic Three-layer Architecture

alt text

(open on draw.io)

Modern Four-layer Architecture

alt text

(open on draw.io)

Layer Dependencies

alt text

(open on draw.io)

Layer Examples

alt text

(open on draw.io)

Testing Pyramid

alt textalt textalt text

(open on draw.io)

Vertical Slice Architecture (Modular Monolith)

alt text

(open on draw.io)

Solution Structure

alt text

alt text

alt text

How to Run:

Update Configuration

Additional Configuration Sources
  • OpenClassifiedAds.WebMVC/appsettings.json and jump toConfigurationSources section.

    "ConfigurationSources":{"SqlServer":{"IsEnabled":false,"ConnectionString":"Server=127.0.0.1;Database=ClassifiedAds;User Id=sa;Password=sqladmin123!@#","SqlQuery":"select [Key], [Value] from ConfigurationEntries"},"AzureKeyVault":{"IsEnabled":false,"VaultName":"https://xxx.vault.azure.net/"}},
  • Get from Sql Server database:

    "ConfigurationSources":{"SqlServer":{"IsEnabled":true,"ConnectionString":"Server=127.0.0.1;Database=ClassifiedAds;User Id=sa;Password=sqladmin123!@#","SqlQuery":"select [Key], [Value] from ConfigurationEntries"},},
  • Get from Azure Key Vault:

    "ConfigurationSources":{"AzureKeyVault":{"IsEnabled":true,"VaultName":"https://xxx.vault.azure.net/"}},
  • Use Both:

    "ConfigurationSources":{"SqlServer":{"IsEnabled":true,"ConnectionString":"Server=127.0.0.1;Database=ClassifiedAds;User Id=sa;Password=sqladmin123!@#","SqlQuery":"select [Key], [Value] from ConfigurationEntries"},"AzureKeyVault":{"IsEnabled":true,"VaultName":"https://xxx.vault.azure.net/"}},
Storage
  • OpenClassifiedAds.WebMVC/appsettings.json,ClassifiedAds.WebAPI/appsettings.json and jump toStorage section.

    "Storage":{"Provider":"Local",},
  • Use Local Files:

    "Storage":{"Provider":"Local","Local":{"Path":"E:\\files"},},
  • Use Azure Blob:

    "Storage":{"Provider":"Azure","Azure":{"ConnectionString":"xxx","Container":"classifiedadds"},},
  • Use Amazon S3:

    "Storage":{"Provider":"Amazon","Amazon":{"AccessKeyID":"xxx","SecretAccessKey":"xxx","BucketName":"classifiedadds","RegionEndpoint":"ap-southeast-1"}},
Message Broker
  • Open below files and jump toMessaging section:

    "Messaging":{"Provider":"RabbitMQ",}
  • Use RabbitMQ

    "Messaging":{"Provider":"RabbitMQ","RabbitMQ":{"HostName":"localhost","UserName":"guest","Password":"guest","ExchangeName":"amq.direct","RoutingKeys":{"FileUploadedEvent":"classifiedadds_fileuploaded","FileDeletedEvent":"classifiedadds_filedeleted","EmailMessageCreatedEvent":"classifiedadds_emailcreated","SmsMessageCreatedEvent":"classifiedadds_smscreated"},"QueueNames":{"FileUploadedEvent":"classifiedadds_fileuploaded","FileDeletedEvent":"classifiedadds_filedeleted","EmailMessageCreatedEvent":"classifiedadds_emailcreated","SmsMessageCreatedEvent":"classifiedadds_smscreated"}}}
  • Use Kafka:

    "Messaging":{"Provider":"Kafka","Kafka":{"BootstrapServers":"localhost:9092","Topics":{"FileUploadedEvent":"classifiedadds_fileuploaded","FileDeletedEvent":"classifiedadds_filedeleted","EmailMessageCreatedEvent":"classifiedadds_emailcreated","SmsMessageCreatedEvent":"classifiedadds_smscreated"},}}
  • Use Azure Queue Storage:

    "Messaging":{"Provider":"AzureQueue","AzureQueue":{"ConnectionString":"xxx","QueueNames":{"FileUploadedEvent":"classifiedadds-fileuploaded","FileDeletedEvent":"classifiedadds-filedeleted","EmailMessageCreatedEvent":"classifiedadds-emailcreated","SmsMessageCreatedEvent":"classifiedadds-smscreated"}}}
  • Use Azure Service Bus:

    "Messaging":{"Provider":"AzureServiceBus","AzureServiceBus":{"ConnectionString":"xxx","QueueNames":{"FileUploadedEvent":"classifiedadds_fileuploaded","FileDeletedEvent":"classifiedadds_filedeleted","EmailMessageCreatedEvent":"classifiedadds_emailcreated","SmsMessageCreatedEvent":"classifiedadds_smscreated"}}}
Logging
  • Open and jump toLogging section of below files:
    "Logging":{"LogLevel":{"Default":"Warning"},"File":{"MinimumLogEventLevel":"Information"},"Elasticsearch":{"IsEnabled":false,"Host":"http://localhost:9200","IndexFormat":"classifiedads","MinimumLogEventLevel":"Information"},"EventLog":{"IsEnabled":false,"LogName":"Application","SourceName":"ClassifiedAds.WebAPI"}},
  • Write to Local file (./logs/log.txt). Always enabled.
    "Logging":{"File":{"MinimumLogEventLevel":"Information"},},
  • Write to Elasticsearch:
    "Logging":{"Elasticsearch":{"IsEnabled":true,"Host":"http://localhost:9200","IndexFormat":"classifiedads","MinimumLogEventLevel":"Information"},},
  • Write to Windows Event Log (Windows only):
    "Logging":{"EventLog":{"IsEnabled":true,"LogName":"Application","SourceName":"ClassifiedAds.WebAPI"}},
  • Enable all options:
    "Logging":{"LogLevel":{"Default":"Warning"},"File":{"MinimumLogEventLevel":"Information"},"Elasticsearch":{"IsEnabled":true,"Host":"http://localhost:9200","IndexFormat":"classifiedads","MinimumLogEventLevel":"Information"},"EventLog":{"IsEnabled":true,"LogName":"Application","SourceName":"ClassifiedAds.WebAPI"}},
Caching
  • Open and jump toCaching section of below files:
    "Caching":{"InMemory":{},"Distributed":{}},
  • Configure options for In Memory Cache:
    "Caching":{"InMemory":{"SizeLimit":null},},
  • Use In Memory Distributed Cache (For Local Testing):
    "Caching":{"Distributed":{"Provider":"InMemory","InMemory":{"SizeLimit":null}}},
  • Use Redis Distributed Cache:
    "Caching":{"Distributed":{"Provider":"Redis","Redis":{"Configuration":"xxx.redis.cache.windows.net:6380,password=xxx,ssl=True,abortConnect=False","InstanceName":""}}},
  • Use Sql Server Distributed Cache:
    dotnettoolinstall--globaldotnet-sql-cache--version="5.0"dotnetsql-cachecreate"Server=127.0.0.1;Database=ClassifiedAds;User Id=sa;Password=sqladmin123!@#"dboCacheEntries
    "Caching":{"Distributed":{"Provider":"SqlServer","SqlServer":{"ConnectionString":"Server=127.0.0.1;Database=ClassifiedAds;User Id=sa;Password=sqladmin123!@#","SchemaName":"dbo","TableName":"CacheEntries"}}},
Monitoring
  • Open and jump toMonitoring section of below files:
    "Monitoring":{},
  • Use Azure Application Insights:
    "Monitoring":{"AzureApplicationInsights":{"IsEnabled":true,"InstrumentationKey":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","EnableSqlCommandTextInstrumentation":true}},
  • Use OpenTelemetry:
    "Monitoring":{"OpenTelemetry":{"IsEnabled":true,"ServiceName":"ClassifiedAds.WebAPI","TraceEnabled":true,"MetricEnabled":true,"Otlp":{"IsEnabled":false,"Endpoint":"http://localhost:4317"}}},
  • Use Both:
    "Monitoring":{"AzureApplicationInsights":{"IsEnabled":true,"InstrumentationKey":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","EnableSqlCommandTextInstrumentation":true},"OpenTelemetry":{"IsEnabled":true,"ServiceName":"ClassifiedAds.WebAPI","TraceEnabled":true,"MetricEnabled":true,"Otlp":{"IsEnabled":false,"Endpoint":"http://localhost:4317"}}},
Interceptors
Security Headers
  • OpenClassifiedAds.WebAPI/appsettings.json and jump toSecurityHeaders section:
    "SecurityHeaders":{"Cache-Control":"no-cache, no-store, must-revalidate","Pragma":"no-cache","Expires":"0"},
  • OpenClassifiedAds.WebMVC/appsettings.json and jump toSecurityHeaders section:
    "SecurityHeaders":{"Content-Security-Policy":"form-action 'self'; frame-ancestors 'none'","Feature-Policy":"camera 'none'","Referrer-Policy":"strict-origin-when-cross-origin","X-Content-Type-Options":"nosniff","X-Frame-Options":"DENY","X-XSS-Protection":"1; mode=block","Cache-Control":"no-cache, no-store, must-revalidate","Pragma":"no-cache","Expires":"0"},
Cross-Origin Resource Sharing (CORS)
  • OpenClassifiedAds.WebAPI/appsettings.json and jump toCORS section:
    "CORS":{"AllowAnyOrigin":false,"AllowedOrigins":["http://localhost:4200","http://localhost:3000","http://localhost:8080"]},
External Login
  • OpenClassifiedAds.IdentityServer/appsettings.json and jump toExternalLogin section:
    "ExternalLogin":{"AzureActiveDirectory":{"IsEnabled":true,"Authority":"https://login.microsoftonline.com/<Directory (tenant) ID>","ClientId":"<Application (client) ID","ClientSecret":"xxx"},"Microsoft":{"IsEnabled":true,"ClientId":"<Application (client) ID","ClientSecret":"xxx"},"Google":{"IsEnabled":true,"ClientId":"xxx","ClientSecret":"xxx"},"Facebook":{"IsEnabled":true,"AppId":"xxx","AppSecret":"xxx"}},
Sending Email
  • OpenClassifiedAds.Background/appsettings.json and jump toNotification -> Email section:
    "Notification":{"Email":{"Provider":"Fake",}}
  • Use SmtpClient:
    "Notification":{"Email":{"Provider":"SmtpClient","SmtpClient":{"Host":"localhost","Port":"","UserName":"","Password":"","EnableSsl":""}}}
Sending SMS
  • OpenClassifiedAds.Background/appsettings.json and jump toNotification -> Sms section:
    "Notification":{"Sms":{"Provider":"Fake",}}
  • Use Twilio
    "Notification":{"Sms":{"Provider":"Twilio","Twilio":{"AccountSId":"","AuthToken":"","FromNumber":""}}}

Run or Debug the Solution

How to Build and Run Single Page Applications:

  • Angular:

  • React:

    • Navigate to folder:UIs/reactjs/

      npm installnpm run dev
    • Updateenvironment.dev.tsx &environment.tsx

      constenvironment={OpenIdConnect:{Authority:"https://localhost:44367",ClientId:"ClassifiedAds.React"},ResourceServer:{Endpoint:"https://localhost:44312/api/"},CurrentUrl:"http://localhost:3000/"};exportdefaultenvironment;
    • Go tohttp://localhost:3000/

      alt text

  • Vue:

    • Navigate to folder:UIs/vuejs/
      npm installnpm run dev
    • Updateenvironment.dev.ts &environment.dev.ts
      constenvironment={OpenIdConnect:{Authority:"https://localhost:44367",ClientId:"ClassifiedAds.Vue"},ResourceServer:{Endpoint:"https://localhost:44312/api/"},CurrentUrl:"http://localhost:8080/"};exportdefaultenvironment;

How to Run on Docker Containers:

How to Run Integration & End to End Tests:

  • UpdateClassifiedAds.IntegrationTests/appsettings.json

    {"OpenIdConnect":{"Authority":"https://localhost:44367","ClientId":"ClassifiedAds.WebMVC","ClientSecret":"secret","RequireHttpsMetadata":"true"},"WebAPI":{"Endpoint":"https://localhost:44312"},"Login":{"UserName":"phong@gmail.com","Password":"v*7Un8b4rcN@<-RN","Scope":"ClassifiedAds.WebAPI"}}
  • DownloadChrome Driver

    alt text

  • UpdateEndToEndUiTests/appsettings.json

    {"ChromeDriverPath":"D:\\Downloads\\chromedriver_win32\\72","Login":{"Url":"https://localhost:44364/Home/Login","UserName":"phong@gmail.com","Password":"v*7Un8b4rcN@<-RN"}}

    alt text

Application URLs:

https://github.com/phongnguyend/Practical.CleanArchitecture/wiki/Application-URLs

Roadmap:

https://github.com/phongnguyend/Practical.CleanArchitecture/wiki/Roadmap

Licence 🔑

This repository is licensed under theMIT license.

Duende.IdentityServer License 🔑

Duende.IdentityServer is available under both aFOSS (RPL) and a commercial license.

For the production environment, it is necessary to get a specific license, if you would like more information about the licensing ofDuende.IdentityServer - please checkthis link.

The source code under/src/IdentityServers/Duende folder uses the source code fromhttps://github.com/DuendeSoftware/IdentityServer.Quickstart.UI which is under the terms of the followinglicense.

About

Full-stack .Net 9 Clean Architecture (Microservices, Modular Monolith, Monolith), Blazor, Angular 20, React 19, Vue 3.5, BFF with YARP, NextJs 15, Domain-Driven Design, CQRS, SOLID, Asp.Net Core Identity Custom Storage, OpenID Connect, EF Core, OpenTelemetry, SignalR, Background Services, Health Checks, Rate Limiting, Clouds (Azure, AWS, GCP), ..

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors8


[8]ページ先頭

©2009-2025 Movatter.jp