├── samples
├── WebNotifier
│ ├── Env
│ │ ├── config.dev.json
│ │ └── config.prod.json
│ ├── Pages
│ │ ├── _ViewImports.cshtml
│ │ ├── Index.cshtml
│ │ ├── Counter.cshtml
│ │ ├── Notification.cshtml
│ │ └── FetchData.cshtml
│ ├── .dockerignore
│ ├── start.sh
│ ├── build.sh
│ ├── wwwroot
│ │ ├── css
│ │ │ └── open-iconic
│ │ │ │ ├── font
│ │ │ │ └── fonts
│ │ │ │ │ ├── open-iconic.eot
│ │ │ │ │ ├── open-iconic.otf
│ │ │ │ │ ├── open-iconic.ttf
│ │ │ │ │ └── open-iconic.woff
│ │ │ │ └── ICON-LICENSE
│ │ ├── index.html
│ │ └── sample-data
│ │ │ └── weather.json
│ ├── _ViewImports.cshtml
│ ├── App.cshtml
│ ├── nginx.conf
│ ├── k8s
│ │ ├── webnotifier-svc.yaml
│ │ └── webnotifier-dep.yaml
│ ├── Shared
│ │ ├── MainLayout.cshtml
│ │ ├── SurveyPrompt.cshtml
│ │ └── NavMenu.cshtml
│ ├── build_image.sh
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Dockerfile
│ ├── Startup.cs
│ └── NetCoreKit.Samples.WebNotifier.csproj
├── TodoApi
│ ├── App_Data
│ │ └── readme.txt
│ ├── .dockerignore
│ ├── App_Build
│ │ ├── start.sh
│ │ ├── build.sh
│ │ ├── k8s
│ │ │ ├── todolist-secrets.yaml
│ │ │ ├── todolist-svc.yaml
│ │ │ ├── todolist-job.yaml
│ │ │ └── todolist-dep.yaml
│ │ ├── gen.sh
│ │ └── build_image.sh
│ ├── Domain
│ │ ├── TaskDeleted.cs
│ │ ├── TaskUpdated.cs
│ │ ├── IUserGateway.cs
│ │ ├── ProjectCreated.cs
│ │ ├── TaskCreated.cs
│ │ └── Project.cs
│ ├── Dtos
│ │ ├── ProjectDto.cs
│ │ ├── TaskDto.cs
│ │ └── AuthorDto.cs
│ ├── v1
│ │ ├── UseCases
│ │ │ ├── ClearTasks
│ │ │ │ ├── Payloads.cs
│ │ │ │ └── RequestHandler.cs
│ │ │ ├── GetTasks
│ │ │ │ ├── Payloads.cs
│ │ │ │ └── RequestHandler.cs
│ │ │ ├── DeleteTask
│ │ │ │ ├── Payloads.cs
│ │ │ │ └── RequestHandler.cs
│ │ │ ├── UpdateTask
│ │ │ │ ├── Payloads.cs
│ │ │ │ └── RequestHandler.cs
│ │ │ ├── CreateProject
│ │ │ │ ├── Payloads.cs
│ │ │ │ └── RequestHandler.cs
│ │ │ └── AddTask
│ │ │ │ ├── Payloads.cs
│ │ │ │ └── RequestHandler.cs
│ │ ├── PubSub
│ │ │ ├── NotifEnvelopeSubscriber.cs
│ │ │ ├── KafkaNotifPublisher.cs
│ │ │ └── RedisNotifPublisher.cs
│ │ └── Mappers
│ │ │ └── ProjectProfile.cs
│ ├── Infrastructure
│ │ ├── Db
│ │ │ ├── TodoListDbContext.cs
│ │ │ └── TodoListDbModelBuilder.cs
│ │ └── Gateways
│ │ │ └── UserGateway.cs
│ ├── Extensions
│ │ ├── TaskExtensions.cs
│ │ └── ProjectExtensions.cs
│ ├── appsettings.Development.json
│ ├── Dockerfile
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Startup.cs
│ ├── appsettings.json
│ └── NetCoreKit.Samples.TodoApi.csproj
├── BiMonetaryApi
│ ├── .dockerignore
│ ├── README.md
│ ├── App_Build
│ │ ├── k8s
│ │ │ ├── bimonetary-svc.yaml
│ │ │ └── bimonetary-dep.yaml
│ │ ├── build_image.sh
│ │ └── gen.sh
│ ├── appsettings.Development.json
│ ├── Program.cs
│ ├── Dockerfile
│ ├── Properties
│ │ └── launchSettings.json
│ ├── v1
│ │ └── Controllers
│ │ │ └── PingController.cs
│ ├── Startup.cs
│ ├── appsettings.json
│ └── NetCoreKit.Samples.BiMonetaryApi.csproj
├── ExchangeService
│ ├── .dockerignore
│ ├── hostsettings.json
│ ├── README.md
│ ├── App_Build
│ │ ├── k8s
│ │ │ ├── exchange-svc.yaml
│ │ │ └── exchange-dep.yaml
│ │ ├── build_image.sh
│ │ └── gen.sh
│ ├── appsettings.json
│ ├── v1
│ │ └── Services
│ │ │ ├── HealthImpl.cs
│ │ │ └── ExchangeServiceImpl.cs
│ └── Dockerfile
├── Notifier
│ ├── hostsettings.json
│ ├── appsettings.json
│ └── App_Build
│ │ └── gen.sh
├── SignalRNotifier
│ ├── App_Build
│ │ ├── start.sh
│ │ ├── build.sh
│ │ ├── k8s
│ │ │ ├── signalrnotifier-secrets.yaml
│ │ │ ├── signalrnotifier-svc.yaml
│ │ │ └── signalrnotifier-dep.yaml
│ │ ├── gen.sh
│ │ └── build_image.sh
│ ├── appsettings.Development.json
│ ├── Services
│ │ ├── Events
│ │ │ ├── ProjectCreated.cs
│ │ │ └── TaskCreated.cs
│ │ ├── Mappers
│ │ │ └── ProjectProfile.cs
│ │ └── HostedService.cs
│ ├── appsettings.json
│ ├── Dockerfile
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ └── NetCoreKit.Samples.SignalRNotifier.csproj
├── _deploys
│ ├── mongo
│ │ ├── mongodb-svc.yaml
│ │ └── mongodb-dep.yaml
│ ├── scripts
│ │ ├── apply-k8s.ps1
│ │ ├── delete-k8s.ps1
│ │ ├── build-images.sh
│ │ └── build-server-images.sh
│ ├── redis-commander
│ │ ├── service.yaml
│ │ └── deployment.yaml
│ ├── kafka-topics-ui
│ │ ├── readme.md
│ │ └── kafka-topics-ui.yaml
│ └── kafka
│ │ ├── kafka-manager.yml
│ │ └── kafka-server.yaml
├── _protos
│ └── v1
│ │ ├── project.proto
│ │ └── bimonetary.proto
└── readme.md
├── global.json
├── .vs
└── netcorekit
│ ├── v15
│ └── .suo
│ ├── v16
│ └── .suo
│ └── DesignTimeBuild
│ └── .dtbcache
├── artwork
└── msa_architecture.png
├── src
├── NetCoreKit.Infrastructure.EfCore.Tests
│ ├── appsettings.json
│ └── NetCoreKit.Infrastructure.EfCore.Tests.csproj
├── NetCoreKit.Infrastructure.EfCore
│ ├── Db
│ │ ├── IDbConnStringFactory.cs
│ │ ├── ICustomModelBuilder.cs
│ │ └── IExtendDbContextOptionsBuilder.cs
│ ├── Migration
│ │ ├── ISeedData.cs
│ │ └── SeedDataBase.cs
│ ├── Extensions
│ │ ├── DbContextExtensions.cs
│ │ └── UnitOfWorkExtensions.cs
│ ├── NetCoreKit.Infrastructure.EfCore.csproj
│ └── ServiceCollectionExtensions.cs
├── NetCoreKit.Utils
│ ├── Attributes
│ │ └── AutoScanAwarenessAttribute.cs
│ ├── Helpers
│ │ ├── DateTimeHelper.cs
│ │ ├── IdHelper.cs
│ │ ├── CryptoRandomHelper.cs
│ │ └── EnumHelper.cs
│ ├── KeyValueResponse.cs
│ ├── README.md
│ ├── Extensions
│ │ ├── TypeConversionExtensions.cs
│ │ ├── DynamicExtensions.cs
│ │ ├── ByteArrayExtensions.cs
│ │ └── AssemblyExtensions.cs
│ └── NetCoreKit.Utils.csproj
├── NetCoreKit.Infrastructure.Bus.Kafka
│ ├── KafkaOptions.cs
│ ├── ProtoSerializer.cs
│ ├── ProtoDeserializer.cs
│ ├── NetCoreKit.Infrastructure.Bus.Kafka.csproj
│ └── ServiceCollectionExtensions.cs
├── NetCoreKit.Infrastructure
│ ├── IExternalSystem.cs
│ ├── Features
│ │ ├── IFeature.cs
│ │ ├── FeatureExtensions.cs
│ │ └── Feature.cs
│ ├── Mappers
│ │ └── AutoMapperProfileExtension.cs
│ ├── NetCoreKit.Infrastructure.csproj
│ ├── OrderByExtensions.cs
│ └── ConfigurationExtensions.cs
├── NetCoreKit.Infrastructure.Mongo
│ ├── MongoSettings.cs
│ ├── IMongoQueryRepository.cs
│ ├── MongoContext.cs
│ ├── QueryRepositoryFactory.cs
│ ├── NetCoreKit.Infrastructure.Mongo.csproj
│ └── UnitOfWorkAsync.cs
├── NetCoreKit.Infrastructure.AspNetCore
│ ├── Validation
│ │ ├── ValidationError.cs
│ │ └── ValidationProblemDetails.cs
│ ├── Authz
│ │ ├── AuthNOptions.cs
│ │ └── AuthAttribute.cs
│ ├── ProxyService.cs
│ ├── HATEOAS
│ │ ├── LinkItem.cs
│ │ └── CriterionExtensions.cs
│ ├── ModelBase.cs
│ ├── Rest
│ │ ├── HttpResponseExtensions.cs
│ │ ├── HttpRequestExtensions.cs
│ │ └── ServiceCollectionExtensions.cs
│ └── Middlewares
│ │ ├── LogHandlerMiddleware.cs
│ │ └── ErrorHandlerMiddleware.cs
├── NetCoreKit.Infrastructure.AspNetCore.OpenApi
│ ├── SwaggerExcludeAttribute.cs
│ ├── OpenApiOptions.cs
│ ├── SwaggerExcludeSchemaFilter.cs
│ ├── NetCoreKit.Infrastructure.AspNetCore.OpenApi.csproj
│ ├── AuthorizeCheckOperationFilter.cs
│ ├── SecurityRequirementsOperationFilter.cs
│ └── DefaultValuesOperationFilter.cs
├── NetCoreKit.Infrastructure.GrpcHost
│ └── CheckPolicyAttribute.cs
├── NetCoreKit.Infrastructure.EfCore.SqlServer
│ ├── Options
│ │ └── DbOptions.cs
│ ├── NetCoreKit.Infrastructure.EfCore.SqlServer.csproj
│ ├── DbContextOptionsBuilderFactory.cs
│ ├── ServiceCollectionExtensions.cs
│ └── DatabaseConnectionStringFactory.cs
├── NetCoreKit.Infrastructure.Bus
│ ├── IDispatchedEventBus.cs
│ ├── ServiceCollectionExtensions.cs
│ ├── DomainEventBus.cs
│ ├── Envelopes.cs
│ └── NetCoreKit.Infrastructure.Bus.csproj
├── NetCoreKit.Infrastructure.AspNetCore.All
│ └── Controllers
│ │ ├── ErrorController.cs
│ │ ├── HomeController.cs
│ │ └── DbMigrationController.cs
├── NetCoreKit.Infrastructure.AspNetCore.CleanArch
│ ├── ServiceCollectionExtensions.cs
│ ├── PresenterExtensions.cs
│ ├── IEventHandler.cs
│ ├── RequestHandlerBase.cs
│ ├── EventAggregatorExtensions.cs
│ ├── TxRequestHandlerBase.cs
│ ├── NetCoreKit.Infrastructure.AspNetCore.CleanArch.csproj
│ └── UnitOfWorkBehavior.cs
├── NetCoreKit.Infrastructure.EfCore.MySql
│ ├── DbOptions.cs
│ ├── NetCoreKit.Infrastructure.EfCore.MySql.csproj
│ ├── ServiceCollectionExtensions.cs
│ ├── DbContextOptionsBuilderFactory.cs
│ └── DatabaseConnectionStringFactory.cs
├── NetCoreKit.Domain
│ ├── QueryRepository.cs
│ ├── NetCoreKit.Domain.csproj
│ ├── Exception.cs
│ ├── UnitOfWork.cs
│ ├── Entity.cs
│ ├── Event.cs
│ ├── ValueObject.cs
│ ├── Identity.cs
│ └── Dto.cs
└── NetCoreKit.Infrastructure.Bus.Redis
│ ├── ServiceCollectionExtensions.cs
│ ├── RedisStore.cs
│ └── NetCoreKit.Infrastructure.Bus.Redis.csproj
├── .dockerignore
├── .github
└── FUNDING.yml
├── appveyor.yml
├── netcorekit.sln.DotSettings
└── LICENSE
/samples/WebNotifier/Env/config.dev.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/samples/TodoApi/App_Data/readme.txt:
--------------------------------------------------------------------------------
1 | Don't delete me!
2 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Pages/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @layout MainLayout
2 |
--------------------------------------------------------------------------------
/samples/TodoApi/.dockerignore:
--------------------------------------------------------------------------------
1 | *
2 | !src
3 | !*.sln
4 | **/bin
5 | **/obj
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "2.2.100"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/.dockerignore:
--------------------------------------------------------------------------------
1 | *
2 | !src
3 | !*.sln
4 | **/bin
5 | **/obj
--------------------------------------------------------------------------------
/samples/WebNotifier/.dockerignore:
--------------------------------------------------------------------------------
1 | *
2 | !src
3 | !*.sln
4 | **/bin
5 | **/obj
--------------------------------------------------------------------------------
/samples/ExchangeService/.dockerignore:
--------------------------------------------------------------------------------
1 | *
2 | !src
3 | !*.sln
4 | **/bin
5 | **/obj
--------------------------------------------------------------------------------
/samples/Notifier/hostsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "environment": "Development"
3 | }
4 |
--------------------------------------------------------------------------------
/samples/TodoApi/App_Build/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -ex
3 |
4 | dotnet run
5 |
--------------------------------------------------------------------------------
/samples/ExchangeService/hostsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "environment": "Development"
3 | }
4 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/App_Build/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -ex
3 |
4 | dotnet run
5 |
--------------------------------------------------------------------------------
/samples/WebNotifier/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -x
4 |
5 | dotnet run
6 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Env/config.prod.json:
--------------------------------------------------------------------------------
1 | {
2 | "SignalRBaseUrl": "http://localhost:32502"
3 | }
4 |
--------------------------------------------------------------------------------
/.vs/netcorekit/v15/.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudnative-netcore/netcorekit/HEAD/.vs/netcorekit/v15/.suo
--------------------------------------------------------------------------------
/.vs/netcorekit/v16/.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudnative-netcore/netcorekit/HEAD/.vs/netcorekit/v16/.suo
--------------------------------------------------------------------------------
/artwork/msa_architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudnative-netcore/netcorekit/HEAD/artwork/msa_architecture.png
--------------------------------------------------------------------------------
/samples/TodoApi/App_Build/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -ex
3 |
4 | export ASPNETCORE_ENVIRONMENT Development
5 | dotnet build
6 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/App_Build/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -ex
3 |
4 | export ASPNETCORE_ENVIRONMENT Development
5 | dotnet build
6 |
--------------------------------------------------------------------------------
/samples/WebNotifier/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -x
4 |
5 | export ASPNETCORE_ENVIRONMENT Development
6 | dotnet build
7 |
--------------------------------------------------------------------------------
/.vs/netcorekit/DesignTimeBuild/.dtbcache:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudnative-netcore/netcorekit/HEAD/.vs/netcorekit/DesignTimeBuild/.dtbcache
--------------------------------------------------------------------------------
/samples/WebNotifier/Pages/Index.cshtml:
--------------------------------------------------------------------------------
1 | @page "/hello"
2 |
3 |
Hello, world!
4 |
5 | Welcome to your new app.
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/WebNotifier/wwwroot/css/open-iconic/font/fonts/open-iconic.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudnative-netcore/netcorekit/HEAD/samples/WebNotifier/wwwroot/css/open-iconic/font/fonts/open-iconic.eot
--------------------------------------------------------------------------------
/samples/WebNotifier/wwwroot/css/open-iconic/font/fonts/open-iconic.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudnative-netcore/netcorekit/HEAD/samples/WebNotifier/wwwroot/css/open-iconic/font/fonts/open-iconic.otf
--------------------------------------------------------------------------------
/samples/WebNotifier/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudnative-netcore/netcorekit/HEAD/samples/WebNotifier/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf
--------------------------------------------------------------------------------
/samples/WebNotifier/wwwroot/css/open-iconic/font/fonts/open-iconic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudnative-netcore/netcorekit/HEAD/samples/WebNotifier/wwwroot/css/open-iconic/font/fonts/open-iconic.woff
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.Tests/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "QualifiedAssemblyPattern": "NetCoreKit.*",
3 | "EfCore": {
4 | "Cache": {
5 | "ExpiredTime": 60 // seconds
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore/Db/IDbConnStringFactory.cs:
--------------------------------------------------------------------------------
1 | namespace NetCoreKit.Infrastructure.EfCore.Db
2 | {
3 | public interface IDbConnStringFactory
4 | {
5 | string Create();
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/samples/TodoApi/Domain/TaskDeleted.cs:
--------------------------------------------------------------------------------
1 | using MediatR;
2 | using NetCoreKit.Domain;
3 |
4 | namespace NetCoreKit.Samples.TodoAPI.Domain
5 | {
6 | public class TaskDeleted : EventBase
7 | {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/samples/TodoApi/Domain/TaskUpdated.cs:
--------------------------------------------------------------------------------
1 | using MediatR;
2 | using NetCoreKit.Domain;
3 |
4 | namespace NetCoreKit.Samples.TodoAPI.Domain
5 | {
6 | public class TaskUpdated : EventBase
7 | {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/Attributes/AutoScanAwarenessAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NetCoreKit.Utils.Attributes
4 | {
5 | public sealed class AutoScanAwarenessAttribute : Attribute
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/samples/Notifier/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Kafka": {
3 | "FQDN": "kafka-server:9092"
4 | },
5 | "Logging": {
6 | "LogLevel": {
7 | "Default": "Warning"
8 | }
9 | },
10 | "AllowedHosts": "*"
11 | }
12 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/App_Build/k8s/signalrnotifier-secrets.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Secret
3 | metadata:
4 | name: signalrnotifier-secrets
5 | namespace: netcorekit
6 | type: Opaque
7 | data:
8 | RedisPassword: bGV0bWVpbg==
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus.Kafka/KafkaOptions.cs:
--------------------------------------------------------------------------------
1 | namespace NetCoreKit.Infrastructure.Bus.Kafka
2 | {
3 | public class KafkaOptions
4 | {
5 | public string Fqdn { get; set; } = "127.0.0.1:9092";
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/README.md:
--------------------------------------------------------------------------------
1 | ### Generating gRPC
2 |
3 | ```
4 | > cd App_Build
5 | > bash
6 | > ./gen.sh
7 | ```
8 |
9 | _Notes_:
10 | - Install necessary libs at https://gist.github.com/thangchung/89c21402b8ffe047267a70d917d2a83e
--------------------------------------------------------------------------------
/samples/ExchangeService/README.md:
--------------------------------------------------------------------------------
1 | ### Generating gRPC
2 |
3 | ```
4 | > cd App_Build
5 | > bash
6 | > ./gen.sh
7 | ```
8 |
9 | _Notes_:
10 | - Install necessary libs at https://gist.github.com/thangchung/89c21402b8ffe047267a70d917d2a83e
--------------------------------------------------------------------------------
/samples/WebNotifier/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using System.Net.Http
2 | @using Microsoft.AspNetCore.Blazor.Layouts
3 | @using Microsoft.AspNetCore.Blazor.Routing
4 | @using Microsoft.JSInterop
5 | @using WebNotifier
6 | @using WebNotifier.Shared
7 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure/IExternalSystem.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace NetCoreKit.Infrastructure
4 | {
5 | public interface IExternalSystem
6 | {
7 | Task Connect();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/samples/TodoApi/App_Build/k8s/todolist-secrets.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Secret
3 | metadata:
4 | name: todolist-secrets
5 | namespace: netcorekit
6 | type: Opaque
7 | data:
8 | MySqlDbPassword: UEBzc3cwcmQ=
9 | RedisPassword: bGV0bWVpbg==
--------------------------------------------------------------------------------
/samples/WebNotifier/App.cshtml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Features": {
3 | "Redis": {
4 | "FQDN": "127.0.0.1:30904",
5 | "Password": "letmein"
6 | },
7 | "Kafka": {
8 | "FQDN": "127.0.0.1:9092"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Mongo/MongoSettings.cs:
--------------------------------------------------------------------------------
1 | namespace NetCoreKit.Infrastructure.Mongo
2 | {
3 | public class MongoSettings
4 | {
5 | public string ConnString { get; set; }
6 | public string Database { get; set; }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/samples/_deploys/mongo/mongodb-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: mongodb
5 | namespace: netcorekit
6 | labels:
7 | app: mongodb
8 | spec:
9 | ports:
10 | - port: 27017
11 | name: mongo
12 | selector:
13 | app: mongodb
--------------------------------------------------------------------------------
/samples/TodoApi/Domain/IUserGateway.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using NetCoreKit.Samples.TodoAPI.Dtos;
3 |
4 | namespace NetCoreKit.Samples.TodoAPI.Domain
5 | {
6 | public interface IUserGateway
7 | {
8 | Task GetAuthorAsync();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/Validation/ValidationError.cs:
--------------------------------------------------------------------------------
1 | namespace NetCoreKit.Infrastructure.AspNetCore.Validation
2 | {
3 | public class ValidationError
4 | {
5 | public string Name { get; set; }
6 | public string Description { get; set; }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore/Db/ICustomModelBuilder.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 |
3 | namespace NetCoreKit.Infrastructure.EfCore.Db
4 | {
5 | public interface ICustomModelBuilder
6 | {
7 | void Build(ModelBuilder modelBuilder);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.OpenApi/SwaggerExcludeAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NetCoreKit.Infrastructure.AspNetCore.OpenApi
4 | {
5 | [AttributeUsage(AttributeTargets.Property)]
6 | public class SwaggerExcludeAttribute : Attribute
7 | {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/samples/_deploys/scripts/apply-k8s.ps1:
--------------------------------------------------------------------------------
1 | Write-Host "Apply for TODO API..."
2 | kubectl apply -f samples/TodoApi/App_Build/k8s/
3 |
4 | Write-Host "Apply for SignalR..."
5 | kubectl apply -f samples/SignalRNotifier/k8s/
6 |
7 | Write-Host "Apply for Web Notifier..."
8 | kubectl apply -f samples/WebNotifier/k8s/
9 |
--------------------------------------------------------------------------------
/samples/WebNotifier/nginx.conf:
--------------------------------------------------------------------------------
1 | events { }
2 | http {
3 | include /etc/nginx/mime.types;
4 |
5 | server {
6 | listen 80;
7 |
8 | location / {
9 | root /usr/share/nginx/html;
10 | try_files $uri $uri/ /Index.html =404;
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/_deploys/scripts/delete-k8s.ps1:
--------------------------------------------------------------------------------
1 | Write-Host "Delete from TODO API..."
2 | kubectl delete -f samples/TodoApi/App_Build/k8s/
3 |
4 | Write-Host "Delete from SignalR..."
5 | kubectl delete -f samples/SignalRNotifier/k8s/
6 |
7 | Write-Host "Delete from Web Notifier..."
8 | kubectl delete -f samples/WebNotifier/k8s/
9 |
--------------------------------------------------------------------------------
/samples/_deploys/scripts/build-images.sh:
--------------------------------------------------------------------------------
1 | chmod +x ./samples/TodoApi/App_Build/build_image.sh
2 | ./samples/TodoApi/build_image.sh
3 |
4 | chmod +x ./samples/SignalRNotifier/build_image.sh
5 | ./samples/SignalRNotifier/build_image.sh
6 |
7 | chmod +x ./samples/WebNotifier/build_image.sh
8 | ./samples/WebNotifier/build_image.sh
9 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/Helpers/DateTimeHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NetCoreKit.Utils.Helpers
4 | {
5 | public static class DateTimeHelper
6 | {
7 | public static DateTime GenerateDateTime()
8 | {
9 | return DateTimeOffset.Now.UtcDateTime;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/samples/ExchangeService/App_Build/k8s/exchange-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: exchange
5 | namespace: netcorekit
6 | labels:
7 | app: exchange
8 | spec:
9 | ports:
10 | - name: grpc
11 | port: 5000
12 | targetPort: 5000
13 | type: ClusterIP
14 | selector:
15 | app: exchange
16 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Mongo/IMongoQueryRepository.cs:
--------------------------------------------------------------------------------
1 | using NetCoreKit.Domain;
2 |
3 | namespace NetCoreKit.Infrastructure.Mongo
4 | {
5 | public interface IMongoQueryRepository : IQueryRepository
6 | where TEntity : IAggregateRoot
7 | {
8 | DbContext DbContext { get; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/Helpers/IdHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NetCoreKit.Utils.Helpers
4 | {
5 | public static class IdHelper
6 | {
7 | public static Guid GenerateId(string guid = "")
8 | {
9 | return string.IsNullOrEmpty(guid) ? Guid.NewGuid() : new Guid(guid);
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/samples/Notifier/App_Build/gen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PROJ_DIR=`pwd`
4 | GRPC_PATH=${HOME}/.nuget/packages/grpc.tools/1.17.1/tools/linux_x64
5 | PROTO_PATH=${PROJ_DIR}/../../_protos/v1
6 | OUTPUT_PATH=${PROJ_DIR}/../Rpc
7 |
8 | $GRPC_PATH/protoc -I $PROTO_PATH -I /usr/local/include \
9 | --csharp_out $OUTPUT_PATH $PROTO_PATH/project.proto
10 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/App_Build/gen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PROJ_DIR=`pwd`
4 | GRPC_PATH=${HOME}/.nuget/packages/grpc.tools/1.17.1/tools/linux_x64
5 | PROTO_PATH=${PROJ_DIR}/../../_protos/v1
6 | OUTPUT_PATH=${PROJ_DIR}/../Rpc
7 |
8 | $GRPC_PATH/protoc -I $PROTO_PATH -I /usr/local/include \
9 | --csharp_out $OUTPUT_PATH $PROTO_PATH/project.proto
10 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure/Features/IFeature.cs:
--------------------------------------------------------------------------------
1 | namespace NetCoreKit.Infrastructure.Features
2 | {
3 | ///
4 | /// Reference at https://github.com/anuraj/AspNetCoreSamples/tree/master/FeatureToggle
5 | ///
6 | public interface IFeature
7 | {
8 | bool IsEnabled(string feature);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/samples/TodoApi/App_Build/gen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -ex
3 |
4 | PROJ_DIR=`pwd`
5 | GRPC_PATH=${HOME}/.nuget/packages/grpc.tools/1.17.1/tools/linux_x64
6 | PROTO_PATH=${PROJ_DIR}/../../_protos/v1
7 | OUTPUT_PATH=${PROJ_DIR}/../v1/Grpc
8 |
9 | $GRPC_PATH/protoc -I $PROTO_PATH -I /usr/local/include \
10 | --csharp_out $OUTPUT_PATH $PROTO_PATH/project.proto
11 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Pages/Counter.cshtml:
--------------------------------------------------------------------------------
1 | @page "/counter"
2 |
3 | Counter
4 |
5 | Current count: @currentCount
6 |
7 |
8 |
9 | @functions {
10 | int currentCount = 0;
11 |
12 | void IncrementCount()
13 | {
14 | currentCount++;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/samples/TodoApi/Dtos/ProjectDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace NetCoreKit.Samples.TodoAPI.Dtos
5 | {
6 | public class ProjectDto
7 | {
8 | public Guid Id { get; set; }
9 | public string Name { get; set; }
10 | public List Tasks { get; set; } = new List();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/samples/WebNotifier/k8s/webnotifier-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: webnotifier
5 | namespace: netcorekit
6 | labels:
7 | app: webnotifier
8 | spec:
9 | ports:
10 | - port: 80
11 | targetPort: 80
12 | nodePort: 32503
13 | protocol: TCP
14 | name: http
15 | type: NodePort
16 | selector:
17 | app: webnotifier
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/KeyValueResponse.cs:
--------------------------------------------------------------------------------
1 | namespace NetCoreKit.Utils
2 | {
3 | public class KeyValueObject
4 | {
5 | public KeyValueObject(TKey key, string value)
6 | {
7 | Key = key;
8 | Value = value;
9 | }
10 |
11 | public TKey Key { get; }
12 | public string Value { get; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/samples/TodoApi/App_Build/build_image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -ex
3 |
4 | TAG=${TAG:=$(git rev-parse --short HEAD)}
5 | NAMESPACE=${NAMESPACE:="vndg"}
6 |
7 | echo "namespace: ${NAMESPACE} and tag: ${TAG}"
8 | echo "start to build TodoApi..."
9 |
10 | docker build -f samples/TodoApi/Dockerfile \
11 | -t $NAMESPACE/todo-api:$TAG \
12 | -t $NAMESPACE/todo-api:latest .
13 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.GrpcHost/CheckPolicyAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NetCoreKit.Infrastructure.GrpcHost
4 | {
5 | public class CheckPolicyAttribute : Attribute
6 | {
7 | public CheckPolicyAttribute(string name)
8 | {
9 | Name = name;
10 | }
11 |
12 | public string Name { get; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/samples/TodoApi/App_Build/k8s/todolist-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: todolist
5 | namespace: netcorekit
6 | labels:
7 | app: todolist
8 | spec:
9 | ports:
10 | - port: 32501
11 | targetPort: 80
12 | nodePort: 32501
13 | protocol: TCP
14 | name: http
15 | type: LoadBalancer
16 | selector:
17 | app: todolist
18 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/Services/Events/ProjectCreated.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using MediatR;
3 |
4 | namespace NetCoreKit.Samples.SignalRNotifier.Services.Events
5 | {
6 | public class ProjectCreated : INotification
7 | {
8 | public Guid Id { get; set; }
9 | public string Name { get; set; }
10 | public DateTime OccurredOn { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/samples/TodoApi/Dtos/TaskDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NetCoreKit.Samples.TodoAPI.Dtos
4 | {
5 | public class TaskDto
6 | {
7 | public Guid Id { get; set; }
8 | public string Title { get; set; }
9 | public int Order { get; set; }
10 | public bool Completed { get; set; }
11 | public string AuthorName { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Shared/MainLayout.cshtml:
--------------------------------------------------------------------------------
1 | @inherits BlazorLayoutComponent
2 |
3 |
6 |
7 |
8 |
11 |
12 |
13 | @Body
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/Validation/ValidationProblemDetails.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace NetCoreKit.Infrastructure.AspNetCore.Validation
5 | {
6 | public class ValidationProblemDetails : ProblemDetails
7 | {
8 | public ICollection ValidationErrors { get; set; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/samples/WebNotifier/build_image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -ex
3 |
4 | TAG=${TAG:=$(git rev-parse --short HEAD)}
5 | NAMESPACE=${NAMESPACE:="vndg"}
6 |
7 | echo "namespace: ${NAMESPACE} and tag: ${TAG}"
8 | echo "start to build WebNotifier..."
9 |
10 | docker build -f samples/WebNotifier/Dockerfile \
11 | -t vndg/webnotifier:$(git rev-parse --short HEAD) \
12 | -t vndg/webnotifier:latest .
13 |
--------------------------------------------------------------------------------
/samples/_deploys/redis-commander/service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: redis-commander
5 | namespace: redis
6 | labels:
7 | app: redis-commander
8 | spec:
9 | ports:
10 | - port: 8081
11 | targetPort: 8081
12 | protocol: TCP
13 | nodePort: 30010
14 | name: redis-commander
15 | type: NodePort
16 | selector:
17 | app: redis-commander
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/App_Build/k8s/bimonetary-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: bimonetary-api
5 | namespace: netcorekit
6 | labels:
7 | app: bimonetary-api
8 | spec:
9 | ports:
10 | - port: 32503
11 | targetPort: 80
12 | nodePort: 32503
13 | protocol: TCP
14 | name: http
15 | type: LoadBalancer
16 | selector:
17 | app: bimonetary-api
18 |
--------------------------------------------------------------------------------
/samples/ExchangeService/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "API_VERSION": "1.0",
3 | "SERVICE_VERSION": "0.0.1",
4 | "QualifiedAssemblyPattern": "NetCoreKit.Samples.*",
5 | "Hosts": {
6 | "Local": {
7 | "Host": "localhost",
8 | "Port": "5000"
9 | }
10 | },
11 | "Logging": {
12 | "LogLevel": {
13 | "Default": "Warning"
14 | }
15 | },
16 | "AllowedHosts": "*"
17 | }
18 |
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Hosts": {
3 | "Externals": {
4 | "CurrentUri": "http://localhost:5002",
5 | "Auth": {
6 | "Uri": "http://localhost:5001"
7 | }
8 | }
9 | },
10 | "Logging": {
11 | "LogLevel": {
12 | "Default": "Debug",
13 | "System": "Information",
14 | "Microsoft": "Information"
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/App_Build/k8s/signalrnotifier-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: signalrnotifier
5 | namespace: netcorekit
6 | labels:
7 | app: signalrnotifier
8 | spec:
9 | ports:
10 | - port: 32502
11 | targetPort: 80
12 | nodePort: 32502
13 | protocol: TCP
14 | name: http
15 | type: LoadBalancer
16 | selector:
17 | app: signalrnotifier
18 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/Authz/AuthNOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace NetCoreKit.Infrastructure.AspNetCore.Authz
4 | {
5 | public class AuthNOptions
6 | {
7 | public Dictionary ClaimToScopeMap { get; set; }
8 | public Dictionary Scopes { get; set; }
9 | public string Audience { get; set; }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/App_Build/build_image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -ex
3 |
4 | readonly TAG=${TAG:=$(git rev-parse --short HEAD)}
5 | readonly NAMESPACE=${NAMESPACE:="vndg"}
6 |
7 | echo "namespace: ${NAMESPACE} and tag: ${TAG}"
8 | echo "start to build BiMonetaryApi..."
9 |
10 | docker build -f samples/BiMonetaryApi/Dockerfile \
11 | -t $NAMESPACE/bimonetary-api:$TAG \
12 | -t $NAMESPACE/bimonetary-api:latest .
13 |
--------------------------------------------------------------------------------
/samples/_deploys/scripts/build-server-images.sh:
--------------------------------------------------------------------------------
1 | TAG=${TAG:=$(git rev-parse --short HEAD)}
2 | NAMESPACE=${NAMESPACE:="vndg"}
3 | echo "${NAMESPACE} and ${TAG}"
4 |
5 | echo "Build TODO API..."
6 | docker build -f samples/TodoApi/Dockerfile -t vndg/todoapi:$TAG -t vndg/todoapi:latest .
7 |
8 | echo "Build SignalR..."
9 | docker build -f samples/SignalRNotifier/Dockerfile -t vndg/signalrnotifier:$TAG -t vndg/signalrnotifier:latest .
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/ProxyService.cs:
--------------------------------------------------------------------------------
1 | using NetCoreKit.Infrastructure.AspNetCore.Rest;
2 |
3 | namespace NetCoreKit.Infrastructure.AspNetCore
4 | {
5 | public abstract class ProxyServiceBase
6 | {
7 | protected readonly RestClient RestClient;
8 |
9 | protected ProxyServiceBase(RestClient rest)
10 | {
11 | RestClient = rest;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore/Db/IExtendDbContextOptionsBuilder.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 |
3 | namespace NetCoreKit.Infrastructure.EfCore.Db
4 | {
5 | public interface IExtendDbContextOptionsBuilder
6 | {
7 | DbContextOptionsBuilder Extend(DbContextOptionsBuilder optionsBuilder,
8 | IDbConnStringFactory connectionStringFactory, string assemblyName);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure/Features/FeatureExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 |
3 | namespace NetCoreKit.Infrastructure.Features
4 | {
5 | public static class FeatureExtensions
6 | {
7 | public static void AddFeatureToggle(this IServiceCollection services)
8 | {
9 | services.AddSingleton(typeof(IFeature), typeof(Feature));
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/samples/ExchangeService/App_Build/build_image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -ex
3 |
4 | readonly TAG=${TAG:=$(git rev-parse --short HEAD)}
5 | readonly NAMESPACE=${NAMESPACE:="vndg"}
6 |
7 | echo "namespace: ${NAMESPACE} and tag: ${TAG}"
8 | echo "start to build ExchangeService..."
9 |
10 | docker build -f samples/ExchangeService/Dockerfile \
11 | -t $NAMESPACE/exchange-service:$TAG \
12 | -t $NAMESPACE/exchange-service:latest .
13 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/App_Build/build_image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -ex
3 |
4 | TAG=${TAG:=$(git rev-parse --short HEAD)}
5 | NAMESPACE=${NAMESPACE:="vndg"}
6 |
7 | echo "namespace: ${NAMESPACE} and tag: ${TAG}"
8 | echo "start to build SignalRNotifier..."
9 |
10 |
11 | docker build -f samples/SignalRNotifier/Dockerfile \
12 | -t vndg/signalrnotifier:$(git rev-parse --short HEAD) \
13 | -t vndg/signalrnotifier:latest .
14 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/Services/Events/TaskCreated.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using MediatR;
3 |
4 | namespace NetCoreKit.Samples.SignalRNotifier.Services.Events
5 | {
6 | public class TaskCreated : INotification
7 | {
8 | public Guid Id { get; set; }
9 | public string Title { get; set; }
10 | public Guid ProjectId { get; set; }
11 | public DateTime OccurredOn { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/TodoApi/Dtos/AuthorDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NetCoreKit.Samples.TodoAPI.Dtos
4 | {
5 | public class AuthorDto
6 | {
7 | public Guid Id { get; set; }
8 | public string FirstName { get; set; }
9 | public string LastName { get; set; }
10 |
11 | public string GetFullName()
12 | {
13 | return $"{FirstName} {LastName}";
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.SqlServer/Options/DbOptions.cs:
--------------------------------------------------------------------------------
1 | namespace NetCoreKit.Infrastructure.EfCore.SqlServer.Options
2 | {
3 | public class DbOptions
4 | {
5 | public string Host { get; set; }
6 | public string Port { get; set; }
7 | public string Database { get; set; }
8 | public string UserName { get; set; }
9 | public string Password { get; set; }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | .dockerignore
2 | .env
3 | .git
4 | .gitignore
5 | .vs
6 | .vscode
7 | docker-compose*.yml
8 | docker-compose.dcproj
9 | *.sln
10 | *.md
11 | LICENSE
12 | *.testsettings
13 | vsts-docs
14 | test
15 | README
16 | **/bin/
17 | **/obj/
18 | **/node_modules/
19 | **/bower_components/
20 | **/appsettings.localhost.json
21 | **/build/
22 | !**/web/build/
23 | **/dist/
24 | deployment
25 | assets
26 | docs
27 | **/*.csproj.user
28 |
--------------------------------------------------------------------------------
/samples/TodoApi/Domain/ProjectCreated.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using NetCoreKit.Domain;
3 |
4 | namespace NetCoreKit.Samples.TodoAPI.Domain
5 | {
6 | public class ProjectCreated : EventBase
7 | {
8 | public ProjectCreated(Guid id, string name)
9 | {
10 | Id = id;
11 | Name = name;
12 | }
13 |
14 | public Guid Id { get; }
15 | public string Name { get; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Blazor.Hosting;
2 |
3 | namespace WebNotifier
4 | {
5 | public class Program
6 | {
7 | public static void Main(string[] args)
8 | {
9 | CreateHostBuilder(args).Build().Run();
10 | }
11 |
12 | public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
13 | BlazorWebAssemblyHost.CreateDefaultBuilder()
14 | .UseBlazorStartup();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus/IDispatchedEventBus.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using Google.Protobuf;
3 |
4 | namespace NetCoreKit.Infrastructure.Bus
5 | {
6 | public interface IDispatchedEventBus
7 | {
8 | Task PublishAsync(TMessage msg, params string[] channels) where TMessage : IMessage;
9 | Task SubscribeAsync(params string[] channels) where TMessage : IMessage, new();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/UseCases/ClearTasks/Payloads.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using MediatR;
3 | using NetCoreKit.Infrastructure.AspNetCore.OpenApi;
4 |
5 | namespace NetCoreKit.Samples.TodoAPI.v1.UseCases.ClearTasks
6 | {
7 | public class ClearTasksRequest : IRequest
8 | {
9 | [SwaggerExclude] public Guid ProjectId { get; set; }
10 | }
11 |
12 | public class ClearTasksResponse
13 | {
14 | public bool Result { get; set; } = true;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.All/Controllers/ErrorController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 | namespace NetCoreKit.Infrastructure.AspNetCore.All.Controllers
4 | {
5 | [Route("")]
6 | [ApiVersionNeutral]
7 | [ApiExplorerSettings(IgnoreApi = true)]
8 | public class ErrorController : Controller
9 | {
10 | [HttpGet("/error")]
11 | public IActionResult Index()
12 | {
13 | return new BadRequestResult();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/Authz/AuthAttribute.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authentication.JwtBearer;
2 | using Microsoft.AspNetCore.Authorization;
3 |
4 | namespace NetCoreKit.Infrastructure.AspNetCore.Authz
5 | {
6 | public class AuthAttribute : AuthorizeAttribute
7 | {
8 | public AuthAttribute(string policy = null)
9 | {
10 | AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme;
11 | Policy = policy;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/HATEOAS/LinkItem.cs:
--------------------------------------------------------------------------------
1 | namespace NetCoreKit.Infrastructure.AspNetCore.HATEOAS
2 | {
3 | public class LinkItem
4 | {
5 | public LinkItem(string href, string rel, string method)
6 | {
7 | Href = href;
8 | Rel = rel;
9 | Method = method;
10 | }
11 |
12 | public string Href { get; set; }
13 | public string Rel { get; set; }
14 | public string Method { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore/Migration/ISeedData.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using Microsoft.EntityFrameworkCore;
3 |
4 | namespace NetCoreKit.Infrastructure.EfCore.Migration
5 | {
6 | public interface ISeedData
7 | where TDbContext : DbContext
8 | {
9 | Task SeedAsync(TDbContext context);
10 | }
11 |
12 | public interface IAuthConfigSeedData : ISeedData
13 | where TDbContext : DbContext
14 | {
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "QualifiedAssemblyPattern": "NetCoreKit.Samples.*",
3 | "Hosts": {
4 | "BasePath": "/"
5 | },
6 | "Logging": {
7 | "IncludeScopes": false,
8 | "Debug": {
9 | "LogLevel": {
10 | "Default": "Warning"
11 | }
12 | },
13 | "Console": {
14 | "LogLevel": {
15 | "Default": "Debug",
16 | "System": "Information",
17 | "Microsoft": "Information"
18 | }
19 | }
20 | },
21 | "AllowedHosts": "*"
22 | }
23 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/UseCases/GetTasks/Payloads.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using MediatR;
3 | using NetCoreKit.Infrastructure.AspNetCore.OpenApi;
4 | using NetCoreKit.Samples.TodoAPI.Dtos;
5 |
6 | namespace NetCoreKit.Samples.TodoAPI.v1.UseCases.GetTasks
7 | {
8 | public class GetTasksRequest : IRequest
9 | {
10 | [SwaggerExclude] public Guid ProjectId { get; set; }
11 | }
12 |
13 | public class GetTasksResponse
14 | {
15 | public ProjectDto Result { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/samples/WebNotifier/wwwroot/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Samples.WebNotifier
7 |
8 |
9 |
10 |
11 |
12 | Loading...
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/samples/TodoApi/Domain/TaskCreated.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using NetCoreKit.Domain;
3 |
4 | namespace NetCoreKit.Samples.TodoAPI.Domain
5 | {
6 | public class TaskCreated : EventBase
7 | {
8 | public TaskCreated(Guid id, string title, Guid projectId)
9 | {
10 | Id = id;
11 | Title = title;
12 | ProjectId = projectId;
13 | }
14 |
15 | public Guid Id { get; }
16 | public string Title { get; }
17 | public Guid ProjectId { get; }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/UseCases/DeleteTask/Payloads.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using MediatR;
3 | using NetCoreKit.Infrastructure.AspNetCore.OpenApi;
4 |
5 | namespace NetCoreKit.Samples.TodoAPI.v1.UseCases.DeleteTask
6 | {
7 | public class DeleteTaskRequest : IRequest
8 | {
9 | [SwaggerExclude] public Guid ProjectId { get; set; }
10 |
11 | public Guid TaskId { get; set; }
12 | }
13 |
14 | public class DeleteTaskResponse
15 | {
16 | public Guid Result { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.CleanArch/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using MediatR;
2 | using Microsoft.Extensions.DependencyInjection;
3 |
4 | namespace NetCoreKit.Infrastructure.AspNetCore.CleanArch
5 | {
6 | public static class ServiceCollectionExtensions
7 | {
8 | public static IServiceCollection AddCleanArch(this IServiceCollection services)
9 | {
10 | services.AddScoped(typeof(IPipelineBehavior<,>), typeof(UnitOfWorkBehavior<,>));
11 | return services;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure/Features/Feature.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Configuration;
2 |
3 | namespace NetCoreKit.Infrastructure.Features
4 | {
5 | public class Feature : IFeature
6 | {
7 | private readonly IConfiguration _config;
8 |
9 | public Feature(IConfiguration config)
10 | {
11 | _config = config;
12 | }
13 |
14 | public bool IsEnabled(string feature)
15 | {
16 | return _config.GetSection($"Features:{feature}").Exists();
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/samples/_protos/v1/project.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package TodoApi;
4 |
5 | option csharp_namespace = "NetCoreKit.Samples.Contracts.TodoApi.v1.Grpc";
6 |
7 | import "google/protobuf/timestamp.proto";
8 |
9 | message ProjectCreatedMsg {
10 | string Key = 1;
11 | string Id = 2;
12 | string Name = 3;
13 | google.protobuf.Timestamp OccurredOn = 4;
14 | }
15 |
16 | message TaskCreatedMsg {
17 | string Key = 1;
18 | string Id = 2;
19 | string Title = 3;
20 | string ProjectId = 4;
21 | google.protobuf.Timestamp OccurredOn = 5;
22 | }
23 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/README.md:
--------------------------------------------------------------------------------
1 | # NetCoreKit.Utils module
2 |
3 | This utils library contains ultility functions and helpers (e.g. string, bytes, hash, modular) that need for the web development.
4 |
5 | # List of utility helper and function
6 |
7 | - Extension functions
8 | - StringExtensions
9 | - AssemblyExtensions
10 | - ByteArrayExtensions
11 | - HashExtensions
12 | - MyModularLookupExtensions
13 |
14 | - Helpers
15 | - CryptoRandomHelper
16 | - DateTimeHelper
17 | - EnumHelper
18 | - IdHelper
19 | - TotpHelper
20 |
21 | - Guard
22 |
23 |
--------------------------------------------------------------------------------
/samples/_deploys/kafka-topics-ui/readme.md:
--------------------------------------------------------------------------------
1 | ### Setup Kafka & its ecosystem
2 |
3 | ```bash
4 | > git clone https://github.com/confluentinc/cp-helm-charts.git
5 | > kubectl create ns kafka
6 | > helm install . --name kafka --namespace kafka
7 | > # helm install cp-helm-charts --name kafka --namespace kafka
8 | ```
9 |
10 | ### Setup kafka-topics-ui
11 |
12 | ```bash
13 | > kubectl create -f kafka-topics-ui.yaml
14 | ```
15 |
16 | ### Dashbard
17 |
18 | ```bash
19 | > http://localhost:8000
20 | ```
21 |
22 | Notes: https://github.com/Landoop/kafka-topics-ui/issues/91
--------------------------------------------------------------------------------
/samples/TodoApi/Infrastructure/Db/TodoListDbContext.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.Extensions.Configuration;
3 | using NetCoreKit.Domain;
4 | using NetCoreKit.Infrastructure.EfCore.Db;
5 |
6 | namespace NetCoreKit.Samples.TodoAPI.Infrastructure.Db
7 | {
8 | public class TodoListDbContext : AppDbContext
9 | {
10 | public TodoListDbContext(DbContextOptions options, IConfiguration config, IDomainEventDispatcher eventBus)
11 | : base(options, config, eventBus)
12 | {
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Shared/SurveyPrompt.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
@Title
4 |
5 |
6 | Please take our
7 | brief survey
8 |
9 | and tell us what you think.
10 |
11 |
12 | @functions {
13 | [Parameter]
14 | string Title { get; set; } // Demonstrates how a parent component can supply parameters
15 | }
16 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Pages/Notification.cshtml:
--------------------------------------------------------------------------------
1 | @using Blazor.Extensions
2 | @page "/"
3 | @inherits WebNotifier.Pages.NotificationComponent
4 | Notification:
5 | @if (Messages.Count <= 0)
6 | {
7 | N/A
8 | }
9 |
10 | @foreach (var m in Messages)
11 | {
12 | - @m
13 | }
14 |
15 |
16 | Projects:
17 | @if (Projects.Count <= 0)
18 | {
19 | N/A
20 | }
21 | @foreach (var p in Projects)
22 | {
23 | @p.Name #@p.Id
24 |
25 | @foreach (var t in p.Tasks)
26 | {
27 | - @t.Title #@t.Id
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/PubSub/NotifEnvelopeSubscriber.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using MediatR;
3 | using NetCoreKit.Infrastructure.Bus;
4 | using Task = System.Threading.Tasks.Task;
5 |
6 | namespace NetCoreKit.Samples.TodoApi.v1.PubSub
7 | {
8 | public class NotifEnvelopeSubscriber : INotificationHandler
9 | {
10 | public async Task Handle(NotificationEnvelope notif, CancellationToken cancellationToken)
11 | {
12 | // do something with @event
13 | //...
14 |
15 | await Task.FromResult(notif);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using Microsoft.Extensions.DependencyInjection.Extensions;
3 | using NetCoreKit.Domain;
4 |
5 | namespace NetCoreKit.Infrastructure.Bus
6 | {
7 | public static class ServiceCollectionExtensions
8 | {
9 | public static IServiceCollection AddDomainEventBus(this IServiceCollection services)
10 | {
11 | services.Replace(ServiceDescriptor.Singleton());
12 | return services;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/App_Build/gen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -ex
3 |
4 | readonly ROOT_DIR=`pwd`
5 | readonly SERVICE_DIR=${ROOT_DIR}/samples/BiMonetaryApi
6 |
7 | readonly GRPC_PATH=${HOME}/.nuget/packages/grpc.tools/1.17.1/tools/linux_x64
8 | readonly PROTO_PATH=${ROOT_DIR}/samples/_protos/v1
9 | readonly OUTPUT_PATH=${SERVICE_DIR}/v1/Grpc
10 | readonly PROTO_FILE=bimonetary.proto
11 |
12 | $GRPC_PATH/protoc -I $PROTO_PATH -I /usr/local/include \
13 | --csharp_out $OUTPUT_PATH \
14 | --grpc_out $OUTPUT_PATH $PROTO_PATH/bimonetary.proto \
15 | --plugin=protoc-gen-grpc=${GRPC_PATH}/grpc_csharp_plugin
16 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.MySql/DbOptions.cs:
--------------------------------------------------------------------------------
1 | namespace NetCoreKit.Infrastructure.EfCore.MySql
2 | {
3 | public class DbOptions
4 | {
5 | public string Host { get; set; }
6 | public string Port { get; set; }
7 | public string Database { get; set; }
8 | public string UserName { get; set; }
9 | public string Password { get; set; }
10 | public string DbInfo { get; set; } = "5.7.14-mysql";
11 | public string ConnString { get; set; } = "server={0};port={1};uid={2};pwd={3};database={4}";
12 | public string FQDN { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.CleanArch/PresenterExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace NetCoreKit.Infrastructure.AspNetCore.CleanArch
5 | {
6 | public static class PresenterExtensions
7 | {
8 | public static IActionResult PresentFor(this TInput input, Func mapTo = null)
9 | where TInput : class
10 | {
11 | if (input == null) return new NoContentResult();
12 |
13 | return mapTo == null ? new OkObjectResult(input) : new OkObjectResult(mapTo(input));
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM microsoft/dotnet:2.2.0-aspnetcore-runtime-alpine AS base
2 | WORKDIR /app
3 |
4 | ENV ASPNETCORE_URLS http://+:80
5 | EXPOSE 80
6 |
7 | FROM microsoft/dotnet:2.2.100-sdk-alpine AS build
8 | WORKDIR .
9 | COPY . .
10 |
11 | WORKDIR /samples/SignalRNotifier
12 |
13 | RUN dotnet restore -nowarn:msb3202,nu1503
14 | RUN dotnet build --no-restore -c Release -o /app
15 |
16 | FROM build AS publish
17 | RUN dotnet publish --no-restore -c Release -o /app
18 |
19 | FROM base AS final
20 | WORKDIR /app
21 | COPY --from=publish /app .
22 | ENTRYPOINT ["dotnet", "NetCoreKit.Samples.SignalRNotifier.dll"]
23 |
--------------------------------------------------------------------------------
/samples/TodoApi/Extensions/TaskExtensions.cs:
--------------------------------------------------------------------------------
1 | using NetCoreKit.Samples.TodoAPI.Domain;
2 | using NetCoreKit.Samples.TodoAPI.Dtos;
3 |
4 | namespace NetCoreKit.Samples.TodoAPI.Extensions
5 | {
6 | public static class TaskExtensions
7 | {
8 | public static TaskDto ToDto(this Task task)
9 | {
10 | return new TaskDto
11 | {
12 | Id = task.Id,
13 | Title = task.Title,
14 | Completed = task.Completed ?? false,
15 | Order = task.Order ?? 1,
16 | AuthorName = task.AuthorName
17 | };
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.CleanArch/IEventHandler.cs:
--------------------------------------------------------------------------------
1 | using MediatR;
2 | using NetCoreKit.Domain;
3 |
4 | namespace NetCoreKit.Infrastructure.AspNetCore.CleanArch
5 | {
6 | public interface IEventHandler : IRequestHandler
7 | where TRequest : IRequest
8 | {
9 | IQueryRepositoryFactory QueryFactory { get; }
10 | }
11 |
12 | public interface ITxEventHandler : IEventHandler
13 | where TRequest : IRequest
14 | {
15 | IUnitOfWorkAsync CommandFactory { get; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/Extensions/TypeConversionExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 |
4 | namespace NetCoreKit.Utils.Extensions
5 | {
6 | public static class TypeConversionExtensions
7 | {
8 | public static T ConvertTo(this string input)
9 | {
10 | try
11 | {
12 | var converter = TypeDescriptor.GetConverter(typeof(T));
13 | return (T)converter.ConvertFromString(input);
14 | }
15 | catch (NotSupportedException)
16 | {
17 | return default(T);
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/samples/_deploys/redis-commander/deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: redis-commander-v1
5 | namespace: redis
6 | spec:
7 | replicas: 1
8 | template:
9 | metadata:
10 | labels:
11 | app: redis-commander
12 | version: v1
13 | spec:
14 | containers:
15 | - name: redis-commander
16 | image: rediscommander/redis-commander
17 | imagePullPolicy: IfNotPresent
18 | env:
19 | - name: REDIS_HOSTS
20 | value: k8s:redis-master:6379:0:letmein
21 | ports:
22 | - name: redis-commander
23 | containerPort: 8081
--------------------------------------------------------------------------------
/samples/ExchangeService/App_Build/gen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -ex
3 |
4 | readonly ROOT_DIR=`pwd`
5 | readonly SERVICE_DIR=${ROOT_DIR}/samples/ExchangeService
6 |
7 | readonly GRPC_PATH=${HOME}/.nuget/packages/grpc.tools/1.17.1/tools/linux_x64
8 | readonly PROTO_PATH=${ROOT_DIR}/samples/_protos/v1
9 | readonly OUTPUT_PATH=${SERVICE_DIR}/v1/Grpc
10 | readonly PROTO_FILE=bimonetary.proto
11 |
12 | cd `$SERVICE_DIR/App_Build`
13 |
14 | $GRPC_PATH/protoc -I $PROTO_PATH -I /usr/local/include \
15 | --csharp_out $OUTPUT_PATH \
16 | --grpc_out $OUTPUT_PATH $PROTO_PATH/$PROTO_FILE \
17 | --plugin=protoc-gen-grpc=${GRPC_PATH}/grpc_csharp_plugin
18 |
19 | cd -
20 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/Extensions/DynamicExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel;
3 | using System.Dynamic;
4 |
5 | namespace NetCoreKit.Utils.Extensions
6 | {
7 | public static class DynamicExtensions
8 | {
9 | public static dynamic ToDynamic(this object value)
10 | {
11 | IDictionary expando = new ExpandoObject();
12 |
13 | foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType()))
14 | expando.Add(property.Name, property.GetValue(value));
15 |
16 | return expando as ExpandoObject;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/samples/_deploys/mongo/mongodb-dep.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: mongodb-v1
5 | namespace: netcorekit
6 | spec:
7 | replicas: 1
8 | template:
9 | metadata:
10 | labels:
11 | app: mongodb
12 | version: v1
13 | spec:
14 | containers:
15 | - name: mongodb
16 | image: bitnami/mongodb:latest
17 | imagePullPolicy: IfNotPresent
18 | ports:
19 | - containerPort: 27017
20 | resources:
21 | requests:
22 | memory: "500Mi"
23 | cpu: "100m"
24 | limits:
25 | memory: "500Mi"
26 | cpu: "100m"
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore/Migration/SeedDataBase.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using Microsoft.EntityFrameworkCore;
3 | using Microsoft.Extensions.Configuration;
4 |
5 | namespace NetCoreKit.Infrastructure.EfCore.Migration
6 | {
7 | public abstract class SeedDataBase : IAuthConfigSeedData
8 | where TDbContext : DbContext
9 | {
10 | protected SeedDataBase(IConfiguration configuration)
11 | {
12 | Configuration = configuration;
13 | }
14 |
15 | protected IConfiguration Configuration { get; }
16 |
17 | public abstract Task SeedAsync(TDbContext context);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Logging;
4 |
5 | namespace NetCoreKit.Samples.BiMonetaryApi
6 | {
7 | public class Program
8 | {
9 | public static void Main(string[] args)
10 | {
11 | CreateWebHostBuilder(args).Build().Run();
12 | }
13 |
14 | public static IWebHostBuilder CreateWebHostBuilder(string[] args)
15 | {
16 | return WebHost.CreateDefaultBuilder(args)
17 | .ConfigureLogging(builder => builder.AddConsole().AddDebug())
18 | .UseStartup();
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/samples/TodoApi/Extensions/ProjectExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using NetCoreKit.Samples.TodoAPI.Dtos;
4 |
5 | namespace NetCoreKit.Samples.TodoAPI.Extensions
6 | {
7 | public static class ProjectExtensions
8 | {
9 | public static ProjectDto ToDto(this Domain.Project prj)
10 | {
11 | return new ProjectDto
12 | {
13 | Id = prj.Id,
14 | Name = prj.Name,
15 | Tasks = prj.Tasks == null
16 | ? new List()
17 | : prj.Tasks.Select(t => t.ToDto()).ToList()
18 | };
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/samples/WebNotifier/k8s/webnotifier-dep.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: webnotifier-v1
5 | namespace: netcorekit
6 | spec:
7 | replicas: 1
8 | template:
9 | metadata:
10 | labels:
11 | app: webnotifier
12 | version: v1
13 | spec:
14 | containers:
15 | - name: webnotifier
16 | image: vndg/webnotifier:latest
17 | imagePullPolicy: IfNotPresent
18 | ports:
19 | - containerPort: 80
20 | resources:
21 | requests:
22 | memory: "64Mi"
23 | cpu: "250m"
24 | limits:
25 | memory: "128Mi"
26 | cpu: "500m"
--------------------------------------------------------------------------------
/samples/ExchangeService/v1/Services/HealthImpl.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using Grpc.Core;
4 | using Grpc.Health.V1;
5 |
6 | namespace NetCoreKit.Samples.ExchangeService.v1.Services
7 | {
8 | public class HealthImpl : Health.HealthBase
9 | {
10 | public override Task Check(HealthCheckRequest request, ServerCallContext context)
11 | {
12 | Console.WriteLine("Checking ExchangeService Health...");
13 |
14 | return Task.FromResult(new HealthCheckResponse
15 | {
16 | Status = HealthCheckResponse.Types.ServingStatus.Serving
17 | });
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Logging;
4 |
5 | namespace NetCoreKit.Samples.SignalRNotifier
6 | {
7 | public class Program
8 | {
9 | public static void Main(string[] args)
10 | {
11 | CreateWebHostBuilder(args).Build().Run();
12 | }
13 |
14 | public static IWebHostBuilder CreateWebHostBuilder(string[] args)
15 | {
16 | return WebHost.CreateDefaultBuilder(args)
17 | .ConfigureLogging(builder => builder.AddConsole().AddDebug())
18 | .UseStartup();
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/samples/TodoApi/Infrastructure/Db/TodoListDbModelBuilder.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using NetCoreKit.Infrastructure.EfCore.Db;
3 |
4 | namespace NetCoreKit.Samples.TodoAPI.Infrastructure.Db
5 | {
6 | public class TodoListDbModelBuilder : ICustomModelBuilder
7 | {
8 | public void Build(ModelBuilder modelBuilder)
9 | {
10 | modelBuilder.Entity(b =>
11 | {
12 | b.HasMany(t => t.Tasks)
13 | .WithOne(a => a.Project)
14 | .HasForeignKey(k => k.ProjectId)
15 | .OnDelete(DeleteBehavior.Cascade);
16 | });
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/samples/TodoApi/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Hosts": {
3 | "Externals": {
4 | "CurrentUri": "http://localhost:5001"
5 | }
6 | },
7 | "Features": {
8 | "EfCore": {
9 | "MySqlDb": {
10 | "FQDN": "127.0.0.1:3306",
11 | "Password": "P@ssw0rd"
12 | }
13 | },
14 | "Redis": {
15 | "FQDN": "127.0.0.1:30904",
16 | "Password": "letmein"
17 | },
18 | "Kafka": {
19 | "FQDN": "127.0.0.1:9092"
20 | }
21 | },
22 | "Logging": {
23 | "IncludeScopes": false,
24 | "LogLevel": {
25 | "Default": "Debug",
26 | "System": "Information",
27 | "Microsoft": "Information"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus/DomainEventBus.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using MediatR;
3 | using NetCoreKit.Domain;
4 |
5 | namespace NetCoreKit.Infrastructure.Bus
6 | {
7 | public class DomainEventDispatcher : IDomainEventDispatcher
8 | {
9 | private readonly IMediator _mediator;
10 |
11 | public DomainEventDispatcher(IMediator mediator)
12 | {
13 | _mediator = mediator;
14 | }
15 |
16 | public async Task Dispatch(IEvent @event)
17 | {
18 | await _mediator.Publish(new NotificationEnvelope(@event));
19 | }
20 |
21 | public void Dispose()
22 | {
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: thangchung
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with a single custom sponsorship URL
13 |
--------------------------------------------------------------------------------
/samples/WebNotifier/wwwroot/sample-data/weather.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "date": "2018-05-06",
4 | "temperatureC": 1,
5 | "summary": "Freezing",
6 | "temperatureF": 33
7 | },
8 | {
9 | "date": "2018-05-07",
10 | "temperatureC": 14,
11 | "summary": "Bracing",
12 | "temperatureF": 57
13 | },
14 | {
15 | "date": "2018-05-08",
16 | "temperatureC": -13,
17 | "summary": "Freezing",
18 | "temperatureF": 9
19 | },
20 | {
21 | "date": "2018-05-09",
22 | "temperatureC": -16,
23 | "summary": "Balmy",
24 | "temperatureF": 4
25 | },
26 | {
27 | "date": "2018-05-10",
28 | "temperatureC": -2,
29 | "summary": "Chilly",
30 | "temperatureF": 29
31 | }
32 | ]
33 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.OpenApi/OpenApiOptions.cs:
--------------------------------------------------------------------------------
1 | namespace NetCoreKit.Infrastructure.AspNetCore.OpenApi
2 | {
3 | public class OpenApiOptions
4 | {
5 | public string Title { get; set; } = "API";
6 | public string Description { get; set; } = "An application with Swagger, Swashbuckle, and API versioning.";
7 | public string ContactName { get; set; } = "Vietnam Devs";
8 | public string ContactEmail { get; set; } = "vietnam.devs.group@gmail.com";
9 | public string TermOfService { get; set; } = "Shareware";
10 | public string LicenseName { get; set; } = "MIT";
11 | public string LicenseUrl { get; set; } = "https://opensource.org/licenses/MIT";
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus.Kafka/ProtoSerializer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Confluent.Kafka.Serialization;
3 | using Google.Protobuf;
4 |
5 | namespace NetCoreKit.Infrastructure.Bus.Kafka
6 | {
7 | public class ProtoSerializer : ISerializer where T : IMessage
8 | {
9 | public IEnumerable>
10 | Configure(IEnumerable> config, bool isKey)
11 | {
12 | return config;
13 | }
14 |
15 | public void Dispose()
16 | {
17 | }
18 |
19 | public byte[] Serialize(string topic, T data)
20 | {
21 | return data.ToByteArray();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Domain/QueryRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace NetCoreKit.Domain
5 | {
6 | public interface IQueryRepositoryFactory
7 | {
8 | IQueryRepositoryWithId QueryRepository() where TEntity : class, IAggregateRootWithId;
9 | IQueryRepository QueryRepository() where TEntity : class, IAggregateRoot;
10 | }
11 |
12 | public interface IQueryRepository : IQueryRepositoryWithId where TEntity : IAggregateRoot
13 | {
14 | }
15 |
16 | public interface IQueryRepositoryWithId where TEntity : IAggregateRootWithId
17 | {
18 | IQueryable Queryable();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/samples/TodoApi/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM microsoft/dotnet:2.2.0-aspnetcore-runtime-alpine AS base
2 | WORKDIR /app
3 |
4 | ARG service_version
5 | ENV SERVICE_VERSION ${service_version:-0.0.1}
6 |
7 | ARG api_version
8 | ENV API_VERSION ${api_version:-1.0}
9 |
10 | ENV ASPNETCORE_URLS http://+:80
11 | EXPOSE 80
12 |
13 | FROM microsoft/dotnet:2.2.100-sdk-alpine AS build
14 | WORKDIR .
15 | COPY . .
16 |
17 | WORKDIR /samples/TodoApi
18 |
19 | RUN dotnet restore -nowarn:msb3202,nu1503
20 | RUN dotnet build --no-restore -c Release -o /app
21 |
22 | FROM build AS publish
23 | RUN dotnet publish --no-restore -c Release -o /app
24 |
25 | FROM base AS final
26 | WORKDIR /app
27 | COPY --from=publish /app .
28 | ENTRYPOINT ["dotnet", "NetCoreKit.Samples.TodoApi.dll"]
29 |
--------------------------------------------------------------------------------
/samples/TodoApi/Infrastructure/Gateways/UserGateway.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using NetCoreKit.Samples.TodoAPI.Domain;
4 | using NetCoreKit.Samples.TodoAPI.Dtos;
5 | using Task = System.Threading.Tasks.Task;
6 |
7 | namespace NetCoreKit.Samples.TodoAPI.Infrastructure.Gateways
8 | {
9 | public class UserGateway : IUserGateway
10 | {
11 | public Task GetAuthorAsync()
12 | {
13 | return Task.FromResult(
14 | new AuthorDto
15 | {
16 | Id = new Guid("E8F0B717-E325-466B-A87C-1AF1AA951599"),
17 | FirstName = "Tom",
18 | LastName = "Cruise"
19 | });
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/ModelBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations;
4 |
5 | namespace NetCoreKit.Infrastructure.AspNetCore
6 | {
7 | public abstract class ModelBase
8 | {
9 | }
10 |
11 | public abstract class IdModelBase : ModelBase
12 | {
13 | [Required] public Guid Id { get; set; }
14 | }
15 |
16 | public abstract class RequestModelBase : ModelBase
17 | {
18 | public IEnumerable> Headers { get; set; }
19 | }
20 |
21 | public abstract class RequestIdModelBase : IdModelBase
22 | {
23 | public IEnumerable> Headers { get; set; }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/samples/TodoApi/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Logging;
4 |
5 | namespace NetCoreKit.Samples.TodoAPI
6 | {
7 | public class Program
8 | {
9 | public static void Main(string[] args)
10 | {
11 | CreateWebHostBuilder(args).Build().Run();
12 | }
13 |
14 | public static IWebHostBuilder CreateWebHostBuilder(string[] args)
15 | {
16 | return WebHost.CreateDefaultBuilder(args)
17 | .ConfigureLogging(builder => builder.AddConsole().AddDebug())
18 | .UseStartup()
19 | .UseDefaultServiceProvider(o => o.ValidateScopes = false /* because of MySQL */);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:5002",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "webnotifier": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | },
24 | "applicationUrl": "http://localhost:5002"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.CleanArch/RequestHandlerBase.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using MediatR;
4 | using NetCoreKit.Domain;
5 |
6 | namespace NetCoreKit.Infrastructure.AspNetCore.CleanArch
7 | {
8 | public abstract class RequestHandlerBase : IEventHandler
9 | where TRequest : IRequest
10 | {
11 | protected RequestHandlerBase(IQueryRepositoryFactory queryRepositoryFactory)
12 | {
13 | QueryFactory = queryRepositoryFactory;
14 | }
15 |
16 | public IQueryRepositoryFactory QueryFactory { get; }
17 |
18 | public abstract Task Handle(TRequest request, CancellationToken cancellationToken);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Mongo/MongoContext.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Options;
2 | using MongoDB.Driver;
3 | using NetCoreKit.Domain;
4 |
5 | namespace NetCoreKit.Infrastructure.Mongo
6 | {
7 | public class DbContext
8 | {
9 | private readonly IMongoDatabase _database;
10 |
11 | public DbContext(IOptions settings)
12 | {
13 | var client = new MongoClient(settings.Value.ConnString);
14 | _database = client.GetDatabase(settings.Value.Database);
15 | }
16 |
17 | public IMongoCollection Collection()
18 | where TEntity : IAggregateRoot
19 | {
20 | return _database.GetCollection(typeof(TEntity).FullName);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/samples/TodoApi/App_Build/k8s/todolist-job.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: batch/v1
2 | kind: Job
3 | metadata:
4 | name: todolist-db-schema-migration
5 | namespace: netcorekit
6 | spec:
7 | template:
8 | spec:
9 | containers:
10 | - name: todolist-db-schema-migration
11 | image: vndg/todoapi:latest
12 | imagePullPolicy: Always
13 | env:
14 | - name: Hosts__BasePath
15 | value: /
16 | command:
17 | - "/bin/sh"
18 | - "-c"
19 | - "until nc -z -v -w30 mysql 3306; do echo 'Waiting for database connection...'; sleep 5; done; until nc -z -v -w30 todolist 32501; do echo 'Waiting for todoapi connection...'; sleep 5; done; apk add --no-cache curl; curl http://todolist:32501/db-migration"
20 | restartPolicy: Never
21 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/UseCases/UpdateTask/Payloads.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.DataAnnotations;
3 | using MediatR;
4 | using NetCoreKit.Infrastructure.AspNetCore.OpenApi;
5 | using NetCoreKit.Samples.TodoAPI.Dtos;
6 |
7 | namespace NetCoreKit.Samples.TodoAPI.v1.UseCases.UpdateTask
8 | {
9 | public class UpdateTaskRequest : IRequest
10 | {
11 | [SwaggerExclude] public Guid ProjectId { get; set; }
12 |
13 | internal Guid TaskId { get; set; }
14 | public int? Order { get; set; } = 1;
15 | [Required] public string Title { get; set; }
16 | public bool? Completed { get; set; } = false;
17 | }
18 |
19 | public class UpdateTaskResponse
20 | {
21 | public ProjectDto Result { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:5003/",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "NetCoreKit.Samples.WebNotifier": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | },
24 | "applicationUrl": "http://localhost:5003/"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM microsoft/dotnet:2.2.100-sdk-alpine AS build
2 | WORKDIR .
3 | COPY . .
4 | WORKDIR /samples/WebNotifier
5 |
6 | RUN dotnet restore -nowarn:msb3202,nu1503
7 | RUN dotnet build --no-restore -c Release -o /app
8 |
9 | FROM build AS publish
10 | RUN dotnet publish --no-restore -c Release -o /app/
11 | WORKDIR /app
12 | RUN ls -an
13 |
14 | FROM nginx:alpine
15 | WORKDIR /app
16 | COPY --from=publish /app/WebNotifier/dist /usr/share/nginx/html/
17 | WORKDIR /usr/share/nginx/html/
18 | RUN ls -an
19 | COPY --from=build /samples/WebNotifier/nginx.conf /etc/nginx/nginx.conf
20 | COPY --from=build /samples/WebNotifier/mime.types /etc/nginx/mime.types
21 | RUN chmod 0644 /etc/nginx/nginx.conf
22 | RUN chmod 0644 /etc/nginx/nginx.conf
23 |
24 | CMD ["nginx", "-g", "daemon off;"]
25 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.All/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 | using Microsoft.Extensions.Configuration;
3 | using NetCoreKit.Infrastructure.AspNetCore.Configuration;
4 |
5 | namespace NetCoreKit.Infrastructure.AspNetCore.All.Controllers
6 | {
7 | [Route("")]
8 | [ApiVersionNeutral]
9 | [ApiExplorerSettings(IgnoreApi = true)]
10 | public class HomeController : Controller
11 | {
12 | private readonly string _basePath;
13 |
14 | public HomeController(IConfiguration config)
15 | {
16 | _basePath = config.GetBasePath() ?? "/";
17 | }
18 |
19 | [HttpGet]
20 | public IActionResult Index()
21 | {
22 | return Redirect($"~{_basePath}swagger");
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM microsoft/dotnet:2.2.0-aspnetcore-runtime-alpine AS base
2 | RUN apk update && apk add libc6-compat
3 | WORKDIR /app
4 |
5 | ARG service_version
6 | ENV SERVICE_VERSION ${service_version:-0.0.1}
7 |
8 | ARG api_version
9 | ENV API_VERSION ${api_version:-1.0}
10 |
11 | ENV ASPNETCORE_URLS http://+:80
12 | EXPOSE 80
13 |
14 | FROM microsoft/dotnet:2.2.100-sdk-alpine AS build
15 | WORKDIR .
16 | COPY . .
17 |
18 | WORKDIR /samples/BiMonetaryApi
19 |
20 | RUN dotnet restore -nowarn:msb3202,nu1503
21 | RUN dotnet build --no-restore -c Release -o /app
22 |
23 | FROM build AS publish
24 | RUN dotnet publish --no-restore -c Release -o /app
25 |
26 | FROM base AS final
27 | WORKDIR /app
28 | COPY --from=publish /app .
29 | ENTRYPOINT ["dotnet", "NetCoreKit.Samples.BiMonetaryApi.dll"]
30 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/Extensions/ByteArrayExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace NetCoreKit.Utils.Extensions
5 | {
6 | public static class ByteArrayExtensions
7 | {
8 | public static string ToBase64String(this byte[] input)
9 | {
10 | return Convert.ToBase64String(input);
11 | }
12 |
13 | public static string ToUrlSuitable(this byte[] input)
14 | {
15 | return input.ToBase64String().Replace("+", "-").Replace("/", "_").Replace("=", "%3d");
16 | }
17 |
18 | public static string ToHexString(this byte[] bytes)
19 | {
20 | var hex = new StringBuilder(bytes.Length * 2);
21 | foreach (var b in bytes) hex.AppendFormat("{0:x2}", b);
22 |
23 | return hex.ToString();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore/Extensions/DbContextExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Microsoft.EntityFrameworkCore;
3 | using Microsoft.EntityFrameworkCore.Infrastructure;
4 | using Microsoft.EntityFrameworkCore.Migrations;
5 |
6 | namespace NetCoreKit.Infrastructure.EfCore.Extensions
7 | {
8 | public static class DbContextExtensions
9 | {
10 | public static bool AllMigrationsApplied(this DbContext context)
11 | {
12 | var applied = context.GetService()
13 | .GetAppliedMigrations()
14 | .Select(m => m.MigrationId);
15 |
16 | var total = context.GetService()
17 | .Migrations
18 | .Select(m => m.Key);
19 |
20 | return !total.Except(applied).Any();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/NetCoreKit.Utils.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Utils
7 | 0.0.0
8 | NetCoreKit.Utils
9 | NetCoreKit.Utils
10 | This utils library contains ultility functions and helpers (e.g. string, bytes, hash, modular).
11 | This utils library contains ultility functions and helpers (e.g. string, bytes, hash, modular) that need for the web development.
12 | netstandard2.0
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/samples/_protos/v1/bimonetary.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package BiMonetary;
4 |
5 | option csharp_namespace = "NetCoreKit.Samples.BiMonetaryApi.Rpc";
6 |
7 | import "google/protobuf/empty.proto";
8 |
9 | service ExchangeService {
10 | rpc GetTokenInfo(TokenRequest) returns (TokenResponse);
11 | rpc Ping(google.protobuf.Empty) returns (PingResponse);
12 | }
13 |
14 | message TokenRequest {
15 | string Symbol = 1;
16 | }
17 |
18 | message TokenResponse {
19 | int32 Rank = 1;
20 | double PriceUsd = 2;
21 | double PriceBtc = 3;
22 | double Volumn24hUsd = 4;
23 | double MarketCapUsd = 5;
24 | double AvailableSupply = 6;
25 | double TotalSupply = 7;
26 | string PercentChange1h = 8;
27 | string PercentChange24h = 9;
28 | string PercentChange7d = 10;
29 | }
30 |
31 | message PingResponse {
32 | bool Result = 1;
33 | }
34 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.All/Controllers/DbMigrationController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using Microsoft.AspNetCore.Mvc;
4 | using NetCoreKit.Infrastructure.EfCore.Extensions;
5 |
6 | namespace NetCoreKit.Infrastructure.AspNetCore.All.Controllers
7 | {
8 | [Route("")]
9 | [ApiVersionNeutral]
10 | [ApiExplorerSettings(IgnoreApi = true)]
11 | public class DbMigrationController : Controller
12 | {
13 | private readonly IServiceProvider _svcProvider;
14 |
15 | public DbMigrationController(IServiceProvider svcProvider)
16 | {
17 | _svcProvider = svcProvider;
18 | }
19 |
20 | [HttpGet("/db-migration")]
21 | public Task Index()
22 | {
23 | return Task.Run(() => _svcProvider.MigrateDbContext() != null);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.CleanArch/EventAggregatorExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reactive.Linq;
3 | using System.Reactive.Threading.Tasks;
4 | using System.Threading;
5 | using MediatR;
6 |
7 | namespace NetCoreKit.Infrastructure.AspNetCore.CleanArch
8 | {
9 | public static class EventAggregatorExtensions
10 | {
11 | public static IObservable SendStream(this IMediator mediator,
12 | TRequest request, Func mapTo = null,
13 | CancellationToken token = default(CancellationToken))
14 | where TRequest : IRequest
15 | where TResponse : class
16 | {
17 | return mediator.Send(request, token)
18 | .ToObservable()
19 | .Select(x => x.PresentFor(mapTo));
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/samples/TodoApi/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:5001",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "samples": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | },
24 | "applicationUrl": "http://localhost:5001"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.CleanArch/TxRequestHandlerBase.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using MediatR;
4 | using NetCoreKit.Domain;
5 |
6 | namespace NetCoreKit.Infrastructure.AspNetCore.CleanArch
7 | {
8 | public abstract class TxRequestHandlerBase : ITxEventHandler
9 | where TRequest : IRequest
10 | {
11 | protected TxRequestHandlerBase(IUnitOfWorkAsync uow, IQueryRepositoryFactory queryRepositoryFactory)
12 | {
13 | QueryFactory = queryRepositoryFactory;
14 | CommandFactory = uow;
15 | }
16 |
17 | public IQueryRepositoryFactory QueryFactory { get; }
18 |
19 | public IUnitOfWorkAsync CommandFactory { get; }
20 |
21 | public abstract Task Handle(TRequest request, CancellationToken cancellationToken);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.OpenApi/SwaggerExcludeSchemaFilter.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Reflection;
3 | using Swashbuckle.AspNetCore.Swagger;
4 | using Swashbuckle.AspNetCore.SwaggerGen;
5 |
6 | namespace NetCoreKit.Infrastructure.AspNetCore.OpenApi
7 | {
8 | public class SwaggerExcludeSchemaFilter : ISchemaFilter
9 | {
10 | public void Apply(Schema schema, SchemaFilterContext context)
11 | {
12 | if (schema?.Properties == null) return;
13 |
14 | var excludedProperties = context.SystemType.GetProperties()
15 | .Where(t => t.GetCustomAttribute() != null);
16 | foreach (var excludedProperty in excludedProperties)
17 | if (schema.Properties.ContainsKey(excludedProperty.Name))
18 | schema.Properties.Remove(excludedProperty.Name);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/launchsettings.json",
3 | "iisSettings": {
4 | "windowsAuthentication": false,
5 | "anonymousAuthentication": true,
6 | "iisExpress": {
7 | "applicationUrl": "http://localhost:54408",
8 | "sslPort": 0
9 | }
10 | },
11 | "profiles": {
12 | "IIS Express": {
13 | "commandName": "IISExpress",
14 | "launchBrowser": true,
15 | "launchUrl": "",
16 | "environmentVariables": {
17 | "ASPNETCORE_ENVIRONMENT": "Development"
18 | }
19 | },
20 | "NetCoreKit.Samples.BiMonetaryApi": {
21 | "commandName": "Project",
22 | "launchBrowser": true,
23 | "launchUrl": "",
24 | "applicationUrl": "http://localhost:5002",
25 | "environmentVariables": {
26 | "ASPNETCORE_ENVIRONMENT": "Development"
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Domain/NetCoreKit.Domain.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Domain
7 | 0.0.0
8 | NetCoreKit.Domain
9 | NetCoreKit.Domain
10 | The domain library for Cloud Native .NET Core Kit.
11 | Supports DDD style with event approach in the library.
12 | netstandard2.0
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/App_Build/k8s/signalrnotifier-dep.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: signalrnotifier-v1
5 | namespace: netcorekit
6 | spec:
7 | replicas: 1
8 | template:
9 | metadata:
10 | labels:
11 | app: signalrnotifier
12 | version: v1
13 | spec:
14 | containers:
15 | - name: signalrnotifier
16 | image: vndg/signalrnotifier:latest
17 | imagePullPolicy: IfNotPresent
18 | env:
19 | - name: Hosts__BasePath
20 | value: /
21 | - name: Kafka__FQDN
22 | value: "kafka-cp-kafka.kafka:9092"
23 | - name: Redis__FQDN
24 | value: "redis-master.redis:6379"
25 | - name: Redis__Password
26 | valueFrom:
27 | secretKeyRef:
28 | name: signalrnotifier-secrets
29 | key: RedisPassword
30 | ports:
31 | - containerPort: 80
32 |
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/v1/Controllers/PingController.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using Google.Protobuf.WellKnownTypes;
3 | using Microsoft.AspNetCore.Mvc;
4 | using MyExchangeService = NetCoreKit.Samples.BiMonetaryApi.Rpc.ExchangeService;
5 |
6 | namespace NetCoreKit.Samples.BiMonetaryApi.v1.Controllers
7 | {
8 | [Route("api/ping")]
9 | [ApiController]
10 | public class PingController : ControllerBase
11 | {
12 | private readonly MyExchangeService.ExchangeServiceClient _exchangeServiceClient;
13 |
14 | public PingController(MyExchangeService.ExchangeServiceClient exchangeServiceClient)
15 | {
16 | _exchangeServiceClient = exchangeServiceClient;
17 | }
18 |
19 | [HttpGet]
20 | public async Task Ping()
21 | {
22 | var response = await _exchangeServiceClient.PingAsync(new Empty());
23 | return Ok(response.Result);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus.Kafka/ProtoDeserializer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Confluent.Kafka.Serialization;
3 | using Google.Protobuf;
4 |
5 | namespace NetCoreKit.Infrastructure.Bus.Kafka
6 | {
7 | public class ProtoDeserializer : IDeserializer
8 | where T : IMessage, new()
9 | {
10 | private readonly MessageParser _parser;
11 |
12 | public ProtoDeserializer()
13 | {
14 | _parser = new MessageParser(() => new T());
15 | }
16 |
17 | public IEnumerable>
18 | Configure(IEnumerable> config, bool isKey)
19 | {
20 | return config;
21 | }
22 |
23 | public void Dispose()
24 | {
25 | }
26 |
27 | public T Deserialize(string topic, byte[] data)
28 | {
29 | return _parser.ParseFrom(data);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/UseCases/CreateProject/Payloads.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 | using AutoMapper;
3 | using MediatR;
4 | using NetCoreKit.Infrastructure.Mappers;
5 | using NetCoreKit.Samples.TodoAPI.Domain;
6 | using NetCoreKit.Samples.TodoAPI.Dtos;
7 |
8 | namespace NetCoreKit.Samples.TodoAPI.v1.UseCases.CreateProject
9 | {
10 | public class CreateProjectRequest : IRequest
11 | {
12 | public CreateProjectRequest()
13 | {
14 | Name = "sample project";
15 | }
16 |
17 | [Required] public string Name { get; set; }
18 | }
19 |
20 | public class CreateProjectResponse
21 | {
22 | public ProjectDto Result { get; set; }
23 | }
24 |
25 | public class CreateProjectProfile : Profile
26 | {
27 | public CreateProjectProfile()
28 | {
29 | this.MapMySelf();
30 | this.MapMySelf();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/samples/readme.md:
--------------------------------------------------------------------------------
1 | ### Installation
2 |
3 | - MySQL
4 |
5 | ```bash
6 | > helm install --name mysql --namespace netcorekit stable/mysql --set mysqlRootPassword=P@ssw0rd --set mysqlPassword=P@ssw0rd --set mysqlDatabase=maindb
7 | ```
8 |
9 | - Redis
10 |
11 | ```bash
12 | > helm install --name redis --namespace redis stable/redis --set usePassword=true --set password=letmein
13 | ```
14 |
15 | - Kafka
16 |
17 | ```bash
18 | > git clone https://github.com/confluentinc/cp-helm-charts.git
19 | > kubectl ns create kafka
20 | > helm install cp-helm-charts --name kafka --namespace kafka
21 | ```
22 |
23 | - Build all solutions
24 | - Run multiple projects `NetCoreKit.Samples.TodoAPI`, `NetCoreKit.Samples.SignalRNotifier`, and `NetCoreKit.Samples.WebNotifier`
25 |
26 | - Run one-off tasks (e.g. database migration)
27 |
28 | ```bash
29 | > kubectl apply -f samples/TodoApi/k8s/todolist-job.yaml
30 | ```
31 |
32 | **Notes**: Change configuration in appsettings.Development.json with your configuration on your local machine.
33 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Mongo/QueryRepositoryFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using NetCoreKit.Domain;
4 |
5 | namespace NetCoreKit.Infrastructure.Mongo
6 | {
7 | public class QueryRepositoryFactory : IQueryRepositoryFactory
8 | {
9 | private readonly IServiceProvider _serviceProvider;
10 |
11 | public QueryRepositoryFactory(IServiceProvider serviceProvider)
12 | {
13 | _serviceProvider = serviceProvider;
14 | }
15 |
16 | public IQueryRepository QueryRepository() where TEntity : class, IAggregateRoot
17 | {
18 | return _serviceProvider.GetService>();
19 | }
20 |
21 | public IQueryRepositoryWithId QueryRepository() where TEntity : class, IAggregateRootWithId
22 | {
23 | return _serviceProvider.GetService>();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/samples/ExchangeService/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM microsoft/dotnet:2.2.0-aspnetcore-runtime-alpine AS base
2 | RUN apk update && apk add libc6-compat
3 | RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \
4 | wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \
5 | chmod +x /bin/grpc_health_probe
6 | WORKDIR /app
7 |
8 | ARG service_version
9 | ENV SERVICE_VERSION ${service_version:-0.0.1}
10 |
11 | ARG api_version
12 | ENV API_VERSION ${api_version:-1.0}
13 |
14 | FROM microsoft/dotnet:2.2.100-sdk-alpine AS build
15 | WORKDIR .
16 | COPY . .
17 |
18 | WORKDIR /samples/ExchangeService
19 |
20 | RUN dotnet restore -nowarn:msb3202,nu1503
21 | RUN dotnet build --no-restore -c Release -o /app
22 |
23 | FROM build AS publish
24 | RUN dotnet publish --no-restore -c Release -o /app
25 |
26 | FROM base AS final
27 | WORKDIR /app
28 | COPY --from=publish /app .
29 | ENTRYPOINT ["dotnet", "NetCoreKit.Samples.ExchangeService.dll"]
30 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/Services/Mappers/ProjectProfile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using AutoMapper;
3 | using NetCoreKit.Samples.Contracts.TodoApi;
4 | using NetCoreKit.Samples.SignalRNotifier.Services.Events;
5 |
6 | namespace NetCoreKit.Samples.SignalRNotifier.Services.Mappers
7 | {
8 | public class ProjectProfile : Profile
9 | {
10 | public ProjectProfile()
11 | {
12 | CreateMap()
13 | .ForMember(x => x.Id, conf => conf.MapFrom(cg => new Guid(cg.Id)))
14 | .ForMember(x => x.ProjectId, conf => conf.MapFrom(cg => new Guid(cg.ProjectId)))
15 | .ForMember(x => x.OccurredOn, conf => conf.MapFrom(cg => cg.OccurredOn.ToDateTime()));
16 |
17 | CreateMap()
18 | .ForMember(x => x.Id, conf => conf.MapFrom(cg => new Guid(cg.Id)))
19 | .ForMember(x => x.OccurredOn, conf => conf.MapFrom(cg => cg.OccurredOn.ToDateTime()));
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/UseCases/CreateProject/RequestHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using MediatR;
4 | using NetCoreKit.Domain;
5 | using NetCoreKit.Samples.TodoAPI.Extensions;
6 |
7 | namespace NetCoreKit.Samples.TodoAPI.v1.UseCases.CreateProject
8 | {
9 | public class RequestHandler : IRequestHandler
10 | {
11 | private readonly IUnitOfWorkAsync _uow;
12 |
13 | public RequestHandler(IUnitOfWorkAsync uow)
14 | {
15 | _uow = uow;
16 | }
17 |
18 | public async Task Handle(CreateProjectRequest request,
19 | CancellationToken cancellationToken)
20 | {
21 | var projectRepository = _uow.RepositoryAsync();
22 |
23 | var result = await projectRepository.AddAsync(Domain.Project.Load(request.Name));
24 |
25 | return new CreateProjectResponse {Result = result.ToDto()};
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/UseCases/AddTask/Payloads.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.DataAnnotations;
3 | using MediatR;
4 | using NetCoreKit.Infrastructure.AspNetCore.OpenApi;
5 | using NetCoreKit.Samples.TodoAPI.Dtos;
6 |
7 | namespace NetCoreKit.Samples.TodoAPI.v1.UseCases.AddTask
8 | {
9 | public class AddTaskRequest : IRequest
10 | {
11 | public AddTaskRequest()
12 | {
13 | Completed = false;
14 | Order = 1;
15 | Title = "sample todo";
16 | AuthorId = new Guid("E8F0B717-E325-466B-A87C-1AF1AA951599"); // we have it in db
17 | }
18 |
19 | [SwaggerExclude] public Guid ProjectId { get; set; }
20 |
21 | public int? Order { get; set; }
22 | [Required] public string Title { get; set; }
23 | public bool? Completed { get; set; }
24 | public Guid AuthorId { get; }
25 | }
26 |
27 | public class AddTaskResponse
28 | {
29 | public ProjectDto Result { get; set; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Domain/Exception.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NetCoreKit.Domain
4 | {
5 | public class CoreException : Exception
6 | {
7 | public CoreException(string message)
8 | : this(message, null)
9 | {
10 | }
11 |
12 | public CoreException(string message, Exception innerEx)
13 | : base(message, innerEx)
14 | {
15 | }
16 | }
17 |
18 | public class DomainException : CoreException
19 | {
20 | public DomainException(string message)
21 | : base(message, null)
22 | {
23 | }
24 | }
25 |
26 | public class ViolateSecurityException : CoreException
27 | {
28 | public ViolateSecurityException(string message)
29 | : base(message, null)
30 | {
31 | }
32 | }
33 |
34 | public class ValidationException : CoreException
35 | {
36 | public ValidationException(string message)
37 | : base(message, null)
38 | {
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.MySql/NetCoreKit.Infrastructure.EfCore.MySql.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Infrastructure.EfCore.MySql
7 | 0.0.0
8 | The EfCore MySQL library for Cloud Native .NET Core Kit.
9 | The MySQL database default for NetCoreKit.Infrastructure.EfCore
10 | netstandard2.0
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | image: Visual Studio 2017
2 |
3 | branches:
4 | only:
5 | - master
6 |
7 | init:
8 | - git config --global core.autocrlf true
9 |
10 | pull_requests:
11 | # Do not increment build number for pull requests
12 | do_not_increment_build_number: true
13 |
14 | nuget:
15 | # Do not publish for pull requests
16 | disable_publish_on_pr: true
17 |
18 | environment:
19 | # Set the DOTNET_SKIP_FIRST_TIME_EXPERIENCE environment variable to stop wasting time caching packages
20 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
21 | # Disable sending usage data to Microsoft
22 | DOTNET_CLI_TELEMETRY_OPTOUT: true
23 |
24 | assembly_info:
25 | patch: false
26 |
27 | configuration:
28 | - Debug
29 |
30 | before_build:
31 | # - ps: choco install dotnetcore-sdk --no-progress --confirm --version 2.2.0
32 | # Display .NET Core version
33 | - cmd: dotnet --version
34 | # Display minimal restore text
35 | - cmd: dotnet restore --verbosity m
36 |
37 | build_script:
38 | - ps: ./build.ps1
39 |
40 | test: off
41 |
42 | skip_tags: true
43 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.SqlServer/NetCoreKit.Infrastructure.EfCore.SqlServer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Infrastructure.EfCore.SqlServer
7 | 0.0.0
8 | The EfCore SqlServer library for Cloud Native .NET Core Kit.
9 | The Microsoft Sql Server default for NetCoreKit.Infrastructure.EfCore.
10 | netstandard2.0
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/samples/_deploys/kafka/kafka-manager.yml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: kafka-manager-v1
5 | namespace: kafka
6 | spec:
7 | replicas: 1
8 | selector:
9 | matchLabels:
10 | app: kafka-manager
11 | template:
12 | metadata:
13 | labels:
14 | app: kafka-manager
15 | version: v1
16 | spec:
17 | containers:
18 | - name: kafka-manager
19 | image: solsson/kafka-manager@sha256:28b1a0b355f3972a9e3b5ac82abcbfee9a72b66a2bfe86094f6ea2caad9ce3a7
20 | ports:
21 | - containerPort: 80
22 | env:
23 | - name: ZK_HOSTS
24 | value: "kafka-cp-zookeeper.kafka:2181"
25 | command:
26 | - ./bin/kafka-manager
27 | - -Dhttp.port=80
28 | ---
29 | apiVersion: v1
30 | kind: Service
31 | metadata:
32 | name: kafka-manager
33 | namespace: kafka
34 | labels:
35 | app: kafka-manager
36 | spec:
37 | selector:
38 | app: kafka-manager
39 | ports:
40 | - protocol: TCP
41 | port: 9000
42 | targetPort: 80
43 | type: LoadBalancer
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/Startup.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using Microsoft.AspNetCore.Builder;
3 | using Microsoft.Extensions.Configuration;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using NetCoreKit.RestTemplate.MongoDb;
6 | using static NetCoreKit.Samples.BiMonetaryApi.Rpc.ExchangeService;
7 |
8 | namespace NetCoreKit.Samples.BiMonetaryApi
9 | {
10 | public class Startup
11 | {
12 | public void ConfigureServices(IServiceCollection services)
13 | {
14 | services.AddMongoDbTemplate(null, (svc, resolver) =>
15 | {
16 | var config = resolver.GetService();
17 | var channel = new Channel(config["RpcClients:ExchangeService"], ChannelCredentials.Insecure);
18 | var client = new ExchangeServiceClient(channel);
19 | services.AddSingleton(typeof(ExchangeServiceClient), client);
20 | });
21 | }
22 |
23 | public void Configure(IApplicationBuilder app)
24 | {
25 | app.UseMongoDbTemplate();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/netcorekit.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
4 | True
5 | True
6 | True
7 | True
8 | True
9 | True
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/Extensions/AssemblyExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using Microsoft.Extensions.DependencyModel;
6 |
7 | namespace NetCoreKit.Utils.Extensions
8 | {
9 | ///
10 | /// https://stackoverflow.com/questions/37895278/how-to-load-assemblies-located-in-a-folder-in-net-core-console-app
11 | ///
12 | public static class AssemblyExtensions
13 | {
14 | public static Assembly FindAssemblyBy(this string assemblyName)
15 | {
16 | var deps = DependencyContext.Default;
17 | var res = deps.CompileLibraries.Where(d => d.Name.Contains(assemblyName)).ToList();
18 | var assembly = Assembly.Load(new AssemblyName(res.First().Name));
19 | return assembly;
20 | }
21 |
22 | public static HashSet GetAssembliesByTypes(this IEnumerable types)
23 | {
24 | return new HashSet(types.Select(type => type.GetTypeInfo().Assembly));
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.Tests/NetCoreKit.Infrastructure.EfCore.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.2
5 | 7.3
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Always
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Domain/UnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 |
5 | namespace NetCoreKit.Domain
6 | {
7 | public interface IUnitOfWorkAsync : IRepositoryFactoryAsync, IDisposable
8 | {
9 | int SaveChanges();
10 | Task SaveChangesAsync(CancellationToken cancellationToken);
11 | }
12 |
13 | public interface IRepositoryFactoryAsync
14 | {
15 | IRepositoryWithIdAsync RepositoryAsync() where TEntity : class, IAggregateRootWithId;
16 | IRepositoryAsync RepositoryAsync() where TEntity : class, IAggregateRoot;
17 | }
18 |
19 | public interface IRepositoryAsync : IRepositoryWithIdAsync where TEntity : IAggregateRoot
20 | {
21 | }
22 |
23 | public interface IRepositoryWithIdAsync where TEntity : IAggregateRootWithId
24 | {
25 | Task AddAsync(TEntity entity);
26 | Task UpdateAsync(TEntity entity);
27 | Task DeleteAsync(TEntity entity);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.SqlServer/DbContextOptionsBuilderFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.EntityFrameworkCore;
3 | using NetCoreKit.Infrastructure.EfCore.Db;
4 |
5 | namespace NetCoreKit.Infrastructure.EfCore.SqlServer
6 | {
7 | public sealed class DbContextOptionsBuilderFactory : IExtendDbContextOptionsBuilder
8 | {
9 | public DbContextOptionsBuilder Extend(
10 | DbContextOptionsBuilder optionsBuilder,
11 | IDbConnStringFactory connectionStringFactory,
12 | string assemblyName)
13 | {
14 | return optionsBuilder.UseSqlServer(
15 | connectionStringFactory.Create(),
16 | sqlOptions =>
17 | {
18 | sqlOptions.MigrationsAssembly(assemblyName);
19 | sqlOptions.EnableRetryOnFailure(
20 | 15,
21 | TimeSpan.FromSeconds(30),
22 | null);
23 | })
24 | .EnableSensitiveDataLogging();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using Microsoft.AspNetCore.Blazor.Builder;
5 | using Microsoft.Extensions.DependencyInjection;
6 | using Microsoft.JSInterop;
7 |
8 | namespace WebNotifier
9 | {
10 | public class Startup
11 | {
12 | public void ConfigureServices(IServiceCollection services)
13 | {
14 | services.AddSingleton(GetConfiguration());
15 | }
16 |
17 | public void Configure(IBlazorApplicationBuilder app)
18 | {
19 | app.AddComponent("app");
20 | }
21 |
22 | public Configuration GetConfiguration()
23 | {
24 | // source: https://github.com/aspnet/Blazor/issues/1152
25 | using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("config.json"))
26 | using (var reader = new StreamReader(stream ?? throw new InvalidOperationException()))
27 | {
28 | return Json.Deserialize(reader.ReadToEnd());
29 | }
30 | }
31 | }
32 |
33 | public class Configuration
34 | {
35 | public string SignalRBaseUrl { get; set; }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/App_Build/k8s/bimonetary-dep.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: bimonetary-api-v1
5 | namespace: netcorekit
6 | spec:
7 | replicas: 1
8 | template:
9 | metadata:
10 | labels:
11 | app: bimonetary-api
12 | version: v1
13 | spec:
14 | containers:
15 | - name: bimonetary-api
16 | image: vndg/bimonetary-api:latest
17 | imagePullPolicy: IfNotPresent
18 | env:
19 | - name: Hosts__BasePath
20 | value: /
21 | - name: Features__Mongo__ConnString
22 | value: mongodb://mongodb:27017
23 | - name: RpcClients__ExchangeService
24 | value: exchange:5000
25 | resources:
26 | requests:
27 | cpu: 200m
28 | memory: 64Mi
29 | limits:
30 | cpu: 300m
31 | memory: 128Mi
32 | ports:
33 | - containerPort: 80
34 | livenessProbe:
35 | httpGet:
36 | path: /healthz
37 | port: 80
38 | initialDelaySeconds: 15
39 | periodSeconds: 10
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 cloud-native-netcore
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/Rest/HttpResponseExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Microsoft.AspNetCore.Http;
3 | using Microsoft.AspNetCore.WebUtilities;
4 | using Newtonsoft.Json;
5 |
6 | namespace NetCoreKit.Infrastructure.AspNetCore.Rest
7 | {
8 | public static class HttpResponseExtensions
9 | {
10 | private static readonly JsonSerializer Serializer = new JsonSerializer
11 | {
12 | NullValueHandling = NullValueHandling.Ignore
13 | };
14 |
15 | public static void WriteJson(this HttpResponse response, T obj, string contentType = null)
16 | {
17 | response.ContentType = contentType ?? "application/json";
18 | using (var writer = new HttpResponseStreamWriter(response.Body, Encoding.UTF8))
19 | {
20 | using (var jsonWriter = new JsonTextWriter(writer))
21 | {
22 | jsonWriter.CloseOutput = false;
23 | jsonWriter.AutoCompleteOnClose = false;
24 |
25 | Serializer.Serialize(jsonWriter, obj);
26 | }
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.CleanArch/NetCoreKit.Infrastructure.AspNetCore.CleanArch.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Infrastructure.AspNetCore.CleanArch
7 | 0.0.0
8 | The Clean Architecture library for Cloud Native .NET Core Kit.
9 | Helps to organize a service structure and architecture according to Clean Architecture.
10 | netstandard2.0
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus.Redis/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Configuration;
2 | using Microsoft.Extensions.DependencyInjection;
3 |
4 | namespace NetCoreKit.Infrastructure.Bus.Redis
5 | {
6 | public static class ServiceCollectionExtensions
7 | {
8 | public static IServiceCollection AddRedisBus(this IServiceCollection services)
9 | {
10 | var resolver = services.BuildServiceProvider();
11 | using (var scope = resolver.CreateScope())
12 | {
13 | var config = scope.ServiceProvider.GetService();
14 | var redisOptions = config.GetSection("Features:Redis");
15 |
16 | services.Configure(o =>
17 | {
18 | o.Fqdn = redisOptions.GetValue("FQDN");
19 | o.Password = redisOptions.GetValue("Password");
20 | });
21 |
22 | services.AddSingleton();
23 | services.AddSingleton();
24 | return services;
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/samples/WebNotifier/wwwroot/css/open-iconic/ICON-LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Waybury
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/Helpers/CryptoRandomHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.Cryptography;
3 | using NetCoreKit.Utils.Extensions;
4 |
5 | namespace NetCoreKit.Utils.Helpers
6 | {
7 | public class CryptoRandomHelper
8 | {
9 | private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();
10 |
11 | public static byte[] CreateRandomBytes(int length)
12 | {
13 | var bytes = new byte[length];
14 | _rng.GetBytes(bytes);
15 |
16 | return bytes;
17 | }
18 |
19 | public static string CreateRandomKey(int length)
20 | {
21 | var bytes = new byte[length];
22 | _rng.GetBytes(bytes);
23 |
24 | return Convert.ToBase64String(CreateRandomBytes(length));
25 | }
26 |
27 | public static string CreateUniqueKey(int length = 8)
28 | {
29 | return CreateRandomBytes(length).ToHexString();
30 | }
31 |
32 | public static string CreateSeriesNumber(string prefix = "MSK")
33 | {
34 | return $"{prefix}{DateTime.Now.ToString("yyyyMMddHHmmss")}{CreateUniqueKey()}";
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.MySql/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Configuration;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using Microsoft.Extensions.DependencyInjection.Extensions;
4 | using NetCoreKit.Infrastructure.EfCore.Db;
5 |
6 | namespace NetCoreKit.Infrastructure.EfCore.MySql
7 | {
8 | public static class ServiceCollectionExtensions
9 | {
10 | public static IServiceCollection AddEfCoreMySqlDb(this IServiceCollection services)
11 | {
12 | var svcProvider = services.BuildServiceProvider();
13 | var config = svcProvider.GetRequiredService();
14 |
15 | services.Configure(config.GetSection("Features:EfCore:MySqlDb"));
16 |
17 | services.Replace(
18 | ServiceDescriptor.Scoped<
19 | IDbConnStringFactory,
20 | DbConnStringFactory>());
21 |
22 | services.Replace(
23 | ServiceDescriptor.Scoped<
24 | IExtendDbContextOptionsBuilder,
25 | DbContextOptionsBuilderFactory>());
26 |
27 | return services;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus.Redis/RedisStore.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.Extensions.Options;
3 | using StackExchange.Redis;
4 |
5 | namespace NetCoreKit.Infrastructure.Bus.Redis
6 | {
7 | public class RedisStore
8 | {
9 | private static Lazy _lazyConnection;
10 |
11 | public RedisStore(IOptions redisOptions)
12 | {
13 | var configurationOptions = new ConfigurationOptions
14 | {
15 | EndPoints =
16 | {
17 | redisOptions.Value.Fqdn
18 | },
19 | Password = redisOptions.Value.Password
20 | };
21 |
22 | _lazyConnection =
23 | new Lazy(() => ConnectionMultiplexer.Connect(configurationOptions));
24 | }
25 |
26 | public ConnectionMultiplexer Connection => _lazyConnection.Value;
27 |
28 | public IDatabase RedisCache => Connection.GetDatabase();
29 | }
30 |
31 | public class RedisOptions
32 | {
33 | public string Fqdn { get; set; } = "127.0.0.1:6379";
34 | public string Password { get; set; } = "letmein";
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/Middlewares/LogHandlerMiddleware.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using Microsoft.AspNetCore.Http;
3 | using Microsoft.AspNetCore.Http.Extensions;
4 | using Microsoft.Extensions.Logging;
5 | using static NetCoreKit.Utils.Helpers.IdHelper;
6 |
7 | namespace NetCoreKit.Infrastructure.AspNetCore.Middlewares
8 | {
9 | public class LogHandlerMiddleware
10 | {
11 | private readonly ILogger _logger;
12 | private readonly RequestDelegate _next;
13 |
14 | public LogHandlerMiddleware(ILoggerFactory loggerFactory, RequestDelegate next)
15 | {
16 | _logger = loggerFactory.CreateLogger();
17 | _next = next;
18 | }
19 |
20 | public async Task Invoke(HttpContext context)
21 | {
22 | context.Items["CorrelationId"] = GenerateId();
23 | _logger.LogInformation(
24 | $"About to start {context.Request?.Method} {context.Request?.GetDisplayUrl()} request");
25 |
26 | await _next(context);
27 |
28 | _logger.LogInformation($"Request completed with status code: {context.Response?.StatusCode} ");
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/samples/ExchangeService/App_Build/k8s/exchange-dep.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1beta2
2 | kind: Deployment
3 | metadata:
4 | name: exchange
5 | namespace: netcorekit
6 | labels:
7 | app: exchange
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: exchange
13 | template:
14 | metadata:
15 | labels:
16 | app: exchange
17 | spec:
18 | containers:
19 | - name: exchange
20 | image: vndg/exchange-service:latest
21 | imagePullPolicy: IfNotPresent
22 | env:
23 | - name: Hosts__Local__Host
24 | value: "0.0.0.0"
25 | - name: Hosts__Local__Port
26 | value: "5000"
27 | ports:
28 | - containerPort: 5000
29 | resources:
30 | requests:
31 | cpu: 200m
32 | memory: 64Mi
33 | limits:
34 | cpu: 300m
35 | memory: 128Mi
36 | readinessProbe:
37 | initialDelaySeconds: 15
38 | exec:
39 | command: ["/bin/grpc_health_probe", "-addr=:5000"]
40 | livenessProbe:
41 | initialDelaySeconds: 15
42 | periodSeconds: 10
43 | exec:
44 | command: ["/bin/grpc_health_probe", "-addr=:5000"]
45 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Mongo/NetCoreKit.Infrastructure.Mongo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Infrastructure.Mongo
7 | 0.0.1
8 | The Mongo library for Cloud Native .NET Core Kit.
9 | The MySQL database default for NetCoreKit.Infrastructure.Mongo
10 | netstandard2.0
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/samples/TodoApi/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using NetCoreKit.Infrastructure.Bus;
4 | using NetCoreKit.Infrastructure.Bus.Redis;
5 | using NetCoreKit.Infrastructure.EfCore.MySql;
6 | using NetCoreKit.RestTemplate.EfCore;
7 | using NetCoreKit.Samples.TodoAPI.Domain;
8 | using NetCoreKit.Samples.TodoAPI.Infrastructure.Db;
9 | using NetCoreKit.Samples.TodoAPI.Infrastructure.Gateways;
10 |
11 | namespace NetCoreKit.Samples.TodoAPI
12 | {
13 | public class Startup
14 | {
15 | public void ConfigureServices(IServiceCollection services)
16 | {
17 | services.AddEfCoreTemplate(
18 | svc =>
19 | {
20 | //svc.AddEfSqlLiteDb();
21 | svc.AddEfCoreMySqlDb();
22 | },
23 | (svc, _) => { svc.AddScoped(); }
24 | );
25 |
26 | services.AddDomainEventBus();
27 | //services.AddRedisBus(); //todo: enabled it if using a broker
28 | }
29 |
30 | public void Configure(IApplicationBuilder app)
31 | {
32 | app.UseEfCoreTemplate();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Utils/Helpers/EnumHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace NetCoreKit.Utils.Helpers
6 | {
7 | public class EnumHelper
8 | {
9 | public static IEnumerable> GetEnumKeyValue()
10 | where TKey : class
11 | {
12 | var metas = GetMetadata();
13 | var results = metas.Item1.Zip(metas.Item2, (key, value) =>
14 | new KeyValueObject
15 | (
16 | key,
17 | value
18 | )
19 | );
20 | return results;
21 | }
22 |
23 | public static (IEnumerable, IEnumerable) GetMetadata()
24 | {
25 | var keyArray = (TKey[])Enum.GetValues(typeof(TEnum));
26 | var nameArray = Enum.GetNames(typeof(TEnum));
27 |
28 | IList keys = new List();
29 | foreach (var item in keyArray) keys.Add(item);
30 |
31 | IList names = new List();
32 | foreach (var item in nameArray) names.Add(item);
33 |
34 | return (keys, names);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/Rest/HttpRequestExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using Microsoft.AspNetCore.Http;
4 |
5 | namespace NetCoreKit.Infrastructure.AspNetCore.Rest
6 | {
7 | public static class HttpRequestExtensions
8 | {
9 | ///
10 | /// Follow at http://opentracing.io/documentation/pages/spec
11 | ///
12 | ///
13 | ///
14 | public static IEnumerable> GetOpenTracingInfo(this HttpRequest request)
15 | {
16 | return request.Headers.Where(x =>
17 | x.Key == "x-request-id" ||
18 | x.Key == "x-b3-traceid" ||
19 | x.Key == "x-b3-spanid" ||
20 | x.Key == "x-b3-parentspanid" ||
21 | x.Key == "x-b3-sampled" ||
22 | x.Key == "x-b3-flags" ||
23 | x.Key == "x-ot-span-context" /* || x.Key == "Authorization" */
24 | ).Select(y =>
25 | new KeyValuePair(
26 | y.Key,
27 | y.Value.FirstOrDefault()));
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.SqlServer/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Configuration;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using Microsoft.Extensions.DependencyInjection.Extensions;
4 | using NetCoreKit.Infrastructure.EfCore.Db;
5 | using NetCoreKit.Infrastructure.EfCore.SqlServer.Options;
6 |
7 | namespace NetCoreKit.Infrastructure.EfCore.SqlServer
8 | {
9 | public static class ServiceCollectionExtensions
10 | {
11 | public static IServiceCollection AddEfCoreSqlServerDb(this IServiceCollection services)
12 | {
13 | var svcProvider = services.BuildServiceProvider();
14 | var config = svcProvider.GetRequiredService();
15 |
16 | services.Configure(config.GetSection("k8s:mssqldb"));
17 |
18 | services.Replace(
19 | ServiceDescriptor.Scoped<
20 | IDbConnStringFactory,
21 | DbConnStringFactory>());
22 |
23 | services.Replace(
24 | ServiceDescriptor.Scoped<
25 | IExtendDbContextOptionsBuilder,
26 | DbContextOptionsBuilderFactory>());
27 |
28 | return services;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus/Envelopes.cs:
--------------------------------------------------------------------------------
1 | using Google.Protobuf;
2 | using MediatR;
3 | using NetCoreKit.Domain;
4 |
5 | namespace NetCoreKit.Infrastructure.Bus
6 | {
7 | ///
8 | /// This class contains the domain event which published from domain entity.
9 | /// We use DomainEventBus to handle and publish it back to the specific project,
10 | /// then it will handle and use some of popular event brokers like Redis/Kafka to handle it
11 | ///
12 | public class NotificationEnvelope : INotification
13 | {
14 | public NotificationEnvelope(IEvent @event)
15 | {
16 | Event = @event;
17 | }
18 |
19 | public IEvent Event { get; }
20 | }
21 |
22 | ///
23 | /// This class contains the Protobuf message with the idea that we will use Protobuf
24 | /// for inter-communication bus via event broker like Redis/Kafka
25 | ///
26 | ///
27 | public class MessageEnvelope : INotification
28 | where T : IMessage
29 | {
30 | public MessageEnvelope(IMessage message)
31 | {
32 | Message = message;
33 | }
34 |
35 | public IMessage Message { get; }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/samples/_deploys/kafka/kafka-server.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: kafka-server-v1
5 | namespace: kafka
6 | spec:
7 | replicas: 1
8 | selector:
9 | matchLabels:
10 | app: kafka-server
11 | template:
12 | metadata:
13 | labels:
14 | app: kafka-server
15 | version: v1
16 | spec:
17 | terminationGracePeriodSeconds: 10
18 | hostNetwork: true
19 | containers:
20 | - name: kafka-server
21 | image: spotify/kafka
22 | ports:
23 | - name: kafka
24 | containerPort: 9092
25 | hostPort: 9092
26 | - name: zookeeper
27 | containerPort: 2181
28 | hostPort: 2181
29 | env:
30 | - name: ADVERTISED_HOST
31 | value: "127.0.0.1"
32 | - name: ADVERTISED_PORT
33 | value: "9092"
34 | ---
35 | apiVersion: v1
36 | kind: Service
37 | metadata:
38 | name: kafka-server
39 | namespace: kafka
40 | labels:
41 | app: kafka-server
42 | spec:
43 | selector:
44 | app: kafka-server
45 | ports:
46 | - name: kafka
47 | protocol: TCP
48 | port: 9092
49 | targetPort: 9092
50 | - name: zookeeper
51 | protocol: TCP
52 | port: 2181
53 | targetPort: 2181
54 |
--------------------------------------------------------------------------------
/samples/WebNotifier/NetCoreKit.Samples.WebNotifier.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | dotnet
6 | blazor serve
7 | 7.3
8 | WebNotifier
9 | WebNotifier
10 | true
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | config.json
23 |
24 |
25 | config.json
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/HATEOAS/CriterionExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using NetCoreKit.Domain;
4 |
5 | namespace NetCoreKit.Infrastructure.AspNetCore.HATEOAS
6 | {
7 | public static class CriterionExtensions
8 | {
9 | public static bool HasPrevious(this Criterion criterion)
10 | {
11 | return criterion.CurrentPage > 1;
12 | }
13 |
14 | public static bool HasNext(this Criterion criterion, int totalCount)
15 | {
16 | return criterion.CurrentPage < (int)GetTotalPages(criterion, totalCount);
17 | }
18 |
19 | public static double GetTotalPages(this Criterion criterion, int totalCount)
20 | {
21 | return Math.Ceiling(totalCount / (double)criterion.PageSize);
22 | }
23 |
24 | public static bool HasQuery(this Criterion criterion)
25 | {
26 | return !string.IsNullOrEmpty(criterion.SortBy);
27 | }
28 |
29 | public static bool IsDescending(this Criterion criterion)
30 | {
31 | if (!string.IsNullOrEmpty(criterion.SortOrder))
32 | return criterion.SortOrder.Split(' ').Last().ToLowerInvariant().StartsWith("desc");
33 | return false;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/samples/TodoApi/App_Build/k8s/todolist-dep.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: todolist-v1
5 | namespace: netcorekit
6 | spec:
7 | replicas: 1
8 | template:
9 | metadata:
10 | labels:
11 | app: todolist
12 | version: v1
13 | spec:
14 | containers:
15 | - name: todolist
16 | image: vndg/todo-api:latest
17 | imagePullPolicy: IfNotPresent
18 | env:
19 | - name: Hosts__BasePath
20 | value: /
21 | - name: MySqlDb__FQDN
22 | value: "mysql.netcorekit:3306"
23 | - name: MySqlDb__Password
24 | valueFrom:
25 | secretKeyRef:
26 | name: todolist-secrets
27 | key: MySqlDbPassword
28 | - name: Kafka__FQDN
29 | value: "kafka-cp-kafka.kafka:9092"
30 | - name: Redis__FQDN
31 | value: "redis-master.redis:6379"
32 | - name: Redis__Password
33 | valueFrom:
34 | secretKeyRef:
35 | name: todolist-secrets
36 | key: RedisPassword
37 | ports:
38 | - containerPort: 80
39 | livenessProbe:
40 | httpGet:
41 | path: /healthz
42 | port: 80
43 | initialDelaySeconds: 15
44 | periodSeconds: 10
45 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus.Redis/NetCoreKit.Infrastructure.Bus.Redis.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Infrastructure.Bus.Redis
7 | 0.0.0
8 | NetCoreKit.Infrastructure.Bus.Redis
9 | NetCoreKit.Infrastructure.Bus.Redis
10 | The redis bus infrastructure library for Cloud Native .NET Core Kit.
11 | Supports Redis Bus for NetCoreKit.Infrastructure.Bus.
12 | netstandard2.0
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.MySql/DbContextOptionsBuilderFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.EntityFrameworkCore;
3 | using Microsoft.Extensions.Options;
4 | using NetCoreKit.Infrastructure.EfCore.Db;
5 |
6 | namespace NetCoreKit.Infrastructure.EfCore.MySql
7 | {
8 | public sealed class DbContextOptionsBuilderFactory : IExtendDbContextOptionsBuilder
9 | {
10 | private readonly DbOptions _options;
11 |
12 | public DbContextOptionsBuilderFactory(IOptions options)
13 | {
14 | _options = options.Value ?? new DbOptions();
15 | }
16 |
17 | public DbContextOptionsBuilder Extend(
18 | DbContextOptionsBuilder optionsBuilder,
19 | IDbConnStringFactory connStringFactory,
20 | string assemblyName)
21 | {
22 | return optionsBuilder.UseMySql(
23 | connStringFactory.Create(),
24 | sqlOptions =>
25 | {
26 | sqlOptions.MigrationsAssembly(assemblyName);
27 | sqlOptions.ServerVersion(_options.DbInfo);
28 | sqlOptions.EnableRetryOnFailure(15, TimeSpan.FromSeconds(30), null);
29 | })
30 | .EnableSensitiveDataLogging();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.CleanArch/UnitOfWorkBehavior.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using MediatR;
4 | using NetCoreKit.Domain;
5 |
6 | namespace NetCoreKit.Infrastructure.AspNetCore.CleanArch
7 | {
8 | ///
9 | /// Source at
10 | /// https://jimmybogard.com/life-beyond-distributed-transactions-an-apostates-implementation-dispatching-example
11 | ///
12 | ///
13 | ///
14 | public class UnitOfWorkBehavior : IPipelineBehavior
15 | {
16 | private readonly IUnitOfWorkAsync _unitOfWork;
17 |
18 | public UnitOfWorkBehavior(IUnitOfWorkAsync unitOfWork)
19 | {
20 | _unitOfWork = unitOfWork;
21 | }
22 |
23 | public async Task Handle(
24 | TRequest request,
25 | CancellationToken cancellationToken,
26 | RequestHandlerDelegate next)
27 | {
28 | using (_unitOfWork)
29 | {
30 | var response = await next();
31 |
32 | await _unitOfWork.SaveChangesAsync(cancellationToken);
33 |
34 | return response;
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus/NetCoreKit.Infrastructure.Bus.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Infrastructure.Bus
7 | 0.0.0
8 | NetCoreKit.Infrastructure.Bus
9 | NetCoreKit.Infrastructure.Bus
10 | The bus infrastructure library for Cloud Native .NET Core Kit.
11 | Supports a very abstraction of the in-memory and utilities for working with the bus.
12 | netstandard2.0
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/Services/HostedService.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using Microsoft.Extensions.Hosting;
4 |
5 | namespace NetCoreKit.Samples.SignalRNotifier.Services
6 | {
7 | ///
8 | /// Source: https://github.com/elucidsoft/aspnetcore-Vue-starter-signalR/blob/master/Services/HostedService.cs
9 | ///
10 | public abstract class HostedService : IHostedService
11 | {
12 | private CancellationTokenSource _cts;
13 | private Task _executingTask;
14 |
15 | public Task StartAsync(CancellationToken cancellationToken)
16 | {
17 | _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
18 |
19 | _executingTask = ExecuteAsync(_cts.Token);
20 |
21 | return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
22 | }
23 |
24 | public async Task StopAsync(CancellationToken cancellationToken)
25 | {
26 | if (_executingTask == null) return;
27 |
28 | _cts.Cancel();
29 |
30 | await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));
31 |
32 | cancellationToken.ThrowIfCancellationRequested();
33 | }
34 |
35 | protected abstract Task ExecuteAsync(CancellationToken cancellationToken);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Domain/Entity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.DataAnnotations;
3 | using static NetCoreKit.Utils.Helpers.IdHelper;
4 | using static NetCoreKit.Utils.Helpers.DateTimeHelper;
5 |
6 | namespace NetCoreKit.Domain
7 | {
8 | public interface IEntity : IEntityWithId
9 | {
10 | }
11 |
12 | ///
13 | ///
14 | /// Supertype for all Entity types
15 | ///
16 | public interface IEntityWithId : IIdentityWithId
17 | {
18 | }
19 |
20 | public abstract class EntityBase : EntityWithIdBase
21 | {
22 | protected EntityBase() : base(GenerateId())
23 | {
24 | }
25 |
26 | protected EntityBase(Guid id) : base(id)
27 | {
28 | }
29 | }
30 |
31 | ///
32 | ///
33 | /// Source: https://github.com/VaughnVernon/IDDD_Samples_NET
34 | ///
35 | public abstract class EntityWithIdBase : IEntityWithId
36 | {
37 | protected EntityWithIdBase(TId id)
38 | {
39 | Id = id;
40 | Created = GenerateDateTime();
41 | }
42 |
43 | public DateTime Created { get; protected set; }
44 |
45 | public DateTime Updated { get; protected set; }
46 |
47 | [Key] public TId Id { get; protected set; }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.SqlServer/DatabaseConnectionStringFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Configuration;
4 | using NetCoreKit.Infrastructure.EfCore.Db;
5 |
6 | namespace NetCoreKit.Infrastructure.EfCore.SqlServer
7 | {
8 | public sealed class DbConnStringFactory : IDbConnStringFactory
9 | {
10 | private readonly IConfiguration _config;
11 | private readonly IHostingEnvironment _env;
12 |
13 | public DbConnStringFactory(
14 | IConfiguration config,
15 | IHostingEnvironment env)
16 | {
17 | _config = config;
18 | _env = env;
19 | }
20 |
21 | public string Create()
22 | {
23 | if (_env.IsDevelopment()) return _config.GetConnectionString("mssqldb");
24 |
25 | return string.Format(
26 | _config.GetConnectionString("mssqldb"),
27 | Environment.GetEnvironmentVariable(_config.GetValue("k8s:mssqldb:Host")),
28 | Environment.GetEnvironmentVariable(_config.GetValue("k8s:mssqldb:Port")),
29 | _config.GetValue("k8s:mssqldb:Database"),
30 | _config.GetValue("k8s:mssqldb:UserName"),
31 | _config.GetValue("k8s:mssqldb:Password"));
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/samples/SignalRNotifier/NetCoreKit.Samples.SignalRNotifier.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.2
5 | true
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/UseCases/GetTasks/RequestHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Microsoft.EntityFrameworkCore;
5 | using NetCoreKit.Domain;
6 | using NetCoreKit.Infrastructure.AspNetCore.CleanArch;
7 | using NetCoreKit.Infrastructure.EfCore.Extensions;
8 | using NetCoreKit.Samples.TodoAPI.Extensions;
9 | using NetCoreKit.Samples.TodoAPI.Infrastructure.Db;
10 |
11 | namespace NetCoreKit.Samples.TodoAPI.v1.UseCases.GetTasks
12 | {
13 | public class RequestHandler : RequestHandlerBase
14 | {
15 | public RequestHandler(IQueryRepositoryFactory queryRepositoryFactory)
16 | : base(queryRepositoryFactory)
17 | {
18 | }
19 |
20 | public override async Task Handle(GetTasksRequest request,
21 | CancellationToken cancellationToken)
22 | {
23 | var queryRepository = QueryFactory.QueryRepository();
24 |
25 | var result = await queryRepository.GetByIdAsync(request.ProjectId, q => q.Include(x => x.Tasks));
26 | if (result == null) throw new Exception($"Couldn't find project#{request.ProjectId}.");
27 |
28 | return new GetTasksResponse
29 | {
30 | Result = result.ToDto()
31 | };
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure/Mappers/AutoMapperProfileExtension.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using MediatR;
3 | using NetCoreKit.Domain;
4 |
5 | namespace NetCoreKit.Infrastructure.Mappers
6 | {
7 | public static class AutoMapperProfileExtension
8 | {
9 | public static Profile MapMySelf(this Profile profile) where TEvent : IEvent
10 | {
11 | profile.CreateMap(typeof(TEvent), typeof(TEvent)).ReverseMap();
12 | return profile;
13 | }
14 |
15 | public static Profile MapTo(this Profile profile)
16 | {
17 | profile.CreateMap(typeof(TSource), typeof(TDestination)).ReverseMap();
18 | return profile;
19 | }
20 |
21 | public static Profile MapToNotification(this Profile profile)
22 | {
23 | // Source: https://stackoverflow.com/questions/13075588/configure-automapper-to-map-to-concrete-types-but-allow-interfaces-in-the-defini/13075915
24 | profile.CreateMap(typeof(TSource), typeof(TDestination));
25 | profile.CreateMap(typeof(TSource), typeof(INotification)).As(typeof(TDestination));
26 | return profile;
27 | }
28 |
29 | public static TDestination MapTo(this TSource request)
30 | {
31 | return Mapper.Map(request);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore/NetCoreKit.Infrastructure.EfCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Infrastructure.EfCore
7 | 0.0.0
8 | The EfCore library for Cloud Native .NET Core Kit.
9 | Helps to add Generic Repository and Unit of Work defaults for a service.
10 | netstandard2.0
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Pages/FetchData.cshtml:
--------------------------------------------------------------------------------
1 | @page "/fetchdata"
2 | @inject HttpClient Http
3 |
4 | Weather forecast
5 |
6 | This component demonstrates fetching data from the server.
7 |
8 | @if (forecasts == null)
9 | {
10 | Loading...
11 | }
12 | else
13 | {
14 |
15 |
16 |
17 | | Date |
18 | Temp. (C) |
19 | Temp. (F) |
20 | Summary |
21 |
22 |
23 |
24 | @foreach (var forecast in forecasts)
25 | {
26 |
27 | | @forecast.Date.ToShortDateString() |
28 | @forecast.TemperatureC |
29 | @forecast.TemperatureF |
30 | @forecast.Summary |
31 |
32 | }
33 |
34 |
35 | }
36 |
37 | @functions {
38 | WeatherForecast[] forecasts;
39 |
40 | protected override async Task OnInitAsync()
41 | {
42 | forecasts = await Http.GetJsonAsync("sample-data/weather.json");
43 | }
44 |
45 | class WeatherForecast
46 | {
47 | public DateTime Date { get; set; }
48 | public int TemperatureC { get; set; }
49 | public int TemperatureF { get; set; }
50 | public string Summary { get; set; }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore/Rest/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Net.Http;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Polly;
6 | using Polly.Extensions.Http;
7 |
8 | namespace NetCoreKit.Infrastructure.AspNetCore.Rest
9 | {
10 | public static class ServiceCollectionExtensions
11 | {
12 | public static IServiceCollection AddHttpPolly(this IServiceCollection services)
13 | where TRestClient : class
14 | {
15 | services.AddHttpClient()
16 | .SetHandlerLifetime(TimeSpan.FromMinutes(1))
17 | .AddPolicyHandler(GetRetryPolicy())
18 | .AddPolicyHandler(GetCircuitBreakerPolicy());
19 |
20 | return services;
21 | }
22 |
23 | private static IAsyncPolicy GetRetryPolicy()
24 | {
25 | return HttpPolicyExtensions
26 | .HandleTransientHttpError()
27 | .OrResult(msg => msg.StatusCode == HttpStatusCode.NotFound)
28 | .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
29 | }
30 |
31 | private static IAsyncPolicy GetCircuitBreakerPolicy()
32 | {
33 | return HttpPolicyExtensions
34 | .HandleTransientHttpError()
35 | .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Domain/Event.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using static NetCoreKit.Utils.Helpers.DateTimeHelper;
5 |
6 | namespace NetCoreKit.Domain
7 | {
8 | ///
9 | /// Supertype for all Event types
10 | ///
11 | public interface IEvent
12 | {
13 | int EventVersion { get; }
14 | DateTime OccurredOn { get; }
15 | }
16 |
17 | public interface IEventHandler
18 | where TEvent : IEvent
19 | {
20 | Task Handle(TEvent request, CancellationToken cancellationToken);
21 | }
22 |
23 | public interface IDomainEventDispatcher : IDisposable
24 | {
25 | Task Dispatch(IEvent @event);
26 | }
27 |
28 | public abstract class EventBase : IEvent
29 | {
30 | public int EventVersion { get; protected set; } = 1;
31 | public DateTime OccurredOn { get; protected set; } = GenerateDateTime();
32 | }
33 |
34 | public class EventEnvelope : EventBase
35 | {
36 | public EventEnvelope(IEvent @event)
37 | {
38 | Event = @event;
39 | }
40 |
41 | public IEvent Event { get; }
42 | }
43 |
44 | public class MemoryDomainEventDispatcher : IDomainEventDispatcher
45 | {
46 | public void Dispose()
47 | {
48 | }
49 |
50 | public Task Dispatch(IEvent @event)
51 | {
52 | return Task.CompletedTask;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.OpenApi/NetCoreKit.Infrastructure.AspNetCore.OpenApi.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Infrastructure.AspNetCore.OpenApi
7 | 0.0.0
8 | The OpenApi library for Cloud Native .NET Core Kit.
9 | Helps to attach the default Swagger and SwaggerUI for a service.
10 | netstandard2.0
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/Mappers/ProjectProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using Google.Protobuf.WellKnownTypes;
3 | using NetCoreKit.Samples.Contracts.TodoApi.v1.Grpc;
4 | using NetCoreKit.Samples.TodoAPI.Domain;
5 |
6 | namespace NetCoreKit.Samples.TodoApi.v1.Mappers
7 | {
8 | public class ProjectProfile : Profile
9 | {
10 | public ProjectProfile()
11 | {
12 | CreateMap()
13 | .ForMember(
14 | x => x.Key,
15 | conf => conf.MapFrom(cg => cg.GetType().Name))
16 | .ForMember(
17 | x => x.Id,
18 | conf => conf.MapFrom(cg => cg.Id.ToString()))
19 | .ForMember(
20 | x => x.OccurredOn,
21 | conf => conf.MapFrom(cg => Timestamp.FromDateTime(cg.OccurredOn)));
22 |
23 | CreateMap()
24 | .ForMember(
25 | x => x.Key,
26 | conf => conf.MapFrom(cg => cg.GetType().Name))
27 | .ForMember(
28 | x => x.Id,
29 | conf => conf.MapFrom(cg => cg.Id.ToString()))
30 | .ForMember(
31 | x => x.ProjectId,
32 | conf => conf.MapFrom(cg => cg.ProjectId.ToString()))
33 | .ForMember(
34 | x => x.OccurredOn,
35 | conf => conf.MapFrom(cg => Timestamp.FromDateTime(cg.OccurredOn)));
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/UseCases/ClearTasks/RequestHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Microsoft.EntityFrameworkCore;
5 | using NetCoreKit.Domain;
6 | using NetCoreKit.Infrastructure.AspNetCore.CleanArch;
7 | using NetCoreKit.Infrastructure.EfCore.Extensions;
8 | using NetCoreKit.Samples.TodoAPI.Infrastructure.Db;
9 |
10 | namespace NetCoreKit.Samples.TodoAPI.v1.UseCases.ClearTasks
11 | {
12 | public class RequestHandler : TxRequestHandlerBase
13 | {
14 | public RequestHandler(IUnitOfWorkAsync uow, IQueryRepositoryFactory queryRepositoryFactory)
15 | : base(uow, queryRepositoryFactory)
16 | {
17 | }
18 |
19 | public override async Task Handle(ClearTasksRequest request,
20 | CancellationToken cancellationToken)
21 | {
22 | var projectRepository = CommandFactory.RepositoryAsync();
23 | var queryRepository = QueryFactory.QueryRepository();
24 |
25 | var project =
26 | await queryRepository.GetByIdAsync(request.ProjectId, q => q.Include(x => x.Tasks), false);
27 | if (project == null)
28 | throw new Exception($"Couldn't found the project#{request.ProjectId}.");
29 |
30 | project.ClearTasks();
31 | await projectRepository.UpdateAsync(project);
32 |
33 | return new ClearTasksResponse();
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/UseCases/DeleteTask/RequestHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Microsoft.EntityFrameworkCore;
5 | using NetCoreKit.Domain;
6 | using NetCoreKit.Infrastructure.AspNetCore.CleanArch;
7 | using NetCoreKit.Infrastructure.EfCore.Extensions;
8 | using NetCoreKit.Samples.TodoAPI.Infrastructure.Db;
9 |
10 | namespace NetCoreKit.Samples.TodoAPI.v1.UseCases.DeleteTask
11 | {
12 | public class RequestHandler : TxRequestHandlerBase
13 | {
14 | public RequestHandler(IUnitOfWorkAsync uow, IQueryRepositoryFactory queryRepositoryFactory)
15 | : base(uow, queryRepositoryFactory)
16 | {
17 | }
18 |
19 | public override async Task Handle(DeleteTaskRequest request,
20 | CancellationToken cancellationToken)
21 | {
22 | var projectRepository = CommandFactory.RepositoryAsync();
23 | var queryRepository = QueryFactory.QueryRepository();
24 |
25 | var project = await queryRepository.GetByIdAsync(request.ProjectId, q => q.Include(x => x.Tasks), false);
26 | if (project == null) throw new Exception($"Couldn't find the project#{request.ProjectId}.");
27 |
28 | project.RemoveTask(request.TaskId);
29 | var result = await projectRepository.UpdateAsync(project);
30 |
31 | return new DeleteTaskResponse {Result = result.Id};
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/samples/WebNotifier/Shared/NavMenu.cshtml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
32 |
33 | @functions {
34 | bool collapseNavMenu = true;
35 |
36 | void ToggleNavMenu()
37 | {
38 | collapseNavMenu = !collapseNavMenu;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/PubSub/KafkaNotifPublisher.cs:
--------------------------------------------------------------------------------
1 | /*using System.Threading;
2 | using MediatR;
3 | using Microsoft.Extensions.Logging;
4 | using NetCoreKit.Infrastructure.Bus;
5 | using NetCoreKit.Infrastructure.Bus.Kafka;
6 | using NetCoreKit.Infrastructure.Mappers;
7 | using NetCoreKit.Samples.TodoAPI.Domain;
8 | using Project.Proto;
9 | using Task = System.Threading.Tasks.Task;
10 |
11 | namespace NetCoreKit.Samples.TodoAPI.v1.Services
12 | {
13 | public class KafkaNotificationPublisher : INotificationHandler
14 | {
15 | private readonly IDispatchedEventBus _eventBus;
16 | private readonly ILogger _logger;
17 |
18 | public KafkaNotificationPublisher(IDispatchedEventBus eventBus, ILoggerFactory loggerFactory)
19 | {
20 | _eventBus = eventBus;
21 | _logger = loggerFactory.CreateLogger();
22 | }
23 |
24 | public async Task Handle(NotificationEnvelope notify, CancellationToken cancellationToken)
25 | {
26 | if (notify.Event is ProjectCreated created)
27 | {
28 | _logger.LogInformation("[NCK] Start to publish ProjectCreatedMsg.");
29 | await _eventBus.Dispatch(created.MapTo(), "project-created");
30 | }
31 | else if(notify.Event is TaskCreated taskCreated)
32 | {
33 | _logger.LogInformation("[NCK] Start to publish TaskCreatedMsg.");
34 | await _eventBus.Dispatch(taskCreated.MapTo(), "task-created");
35 | }
36 | }
37 | }
38 | } */
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.OpenApi/AuthorizeCheckOperationFilter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using Microsoft.AspNetCore.Authorization;
4 | using Swashbuckle.AspNetCore.Swagger;
5 | using Swashbuckle.AspNetCore.SwaggerGen;
6 |
7 | namespace NetCoreKit.Infrastructure.AspNetCore.OpenApi
8 | {
9 | public class AuthorizeCheckOperationFilter : IOperationFilter
10 | {
11 | public void Apply(Operation operation, OperationFilterContext context)
12 | {
13 | // Check for authorize attribute
14 | context.ApiDescription.TryGetMethodInfo(out var methodInfo);
15 | var requiredScopes = methodInfo.GetCustomAttributes(true).OfType();
16 |
17 | /*var hasAuthorize = context.ApiDescription.ControllerAttributes().OfType().Any() ||
18 | context.ApiDescription.ActionAttributes().OfType().Any();*/
19 |
20 | var hasAuthorize = requiredScopes.Any();
21 | if (!hasAuthorize) return;
22 |
23 | operation.Responses.Add("401", new Response {Description = "Unauthorized"});
24 | operation.Responses.Add("403", new Response {Description = "Forbidden"});
25 |
26 | operation.Security = new List>>
27 | {
28 | new Dictionary>
29 | {
30 | ["oauth2"] = new[] {"swagger_id"}
31 | }
32 | };
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.Bus.Kafka/NetCoreKit.Infrastructure.Bus.Kafka.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NetCoreKit.Infrastructure.Bus.Kafka
7 | 0.0.0
8 | NetCoreKit.Infrastructure.Bus.Kafka
9 | NetCoreKit.Infrastructure.Bus.Kafka
10 | The kafka bus infrastructure library for Cloud Native .NET Core Kit.
11 | Supports Kafka Bus for NetCoreKit.Infrastructure.Bus.
12 | netstandard2.0
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore/Extensions/UnitOfWorkExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using Microsoft.EntityFrameworkCore;
4 | using NetCoreKit.Domain;
5 |
6 | namespace NetCoreKit.Infrastructure.EfCore.Extensions
7 | {
8 | public static class EfUnitOfWorkExtensions
9 | {
10 | public static int? GetCommandTimeout(this IUnitOfWorkAsync uow, DbContext context)
11 | {
12 | return context.Database.GetCommandTimeout();
13 | }
14 |
15 | public static IUnitOfWorkAsync SetCommandTimeout(this IUnitOfWorkAsync uow, DbContext context, int? value)
16 | {
17 | context.Database.SetCommandTimeout(value);
18 | return uow;
19 | }
20 |
21 | public static int ExecuteSqlCommand(this IUnitOfWorkAsync uow, DbContext context, string sql,
22 | params object[] parameters)
23 | {
24 | return context.Database.ExecuteSqlCommand(sql, parameters);
25 | }
26 |
27 | public static async Task ExecuteSqlCommandAsync(this IUnitOfWorkAsync uow, DbContext context, string sql,
28 | params object[] parameters)
29 | {
30 | return await context.Database.ExecuteSqlCommandAsync(sql, parameters);
31 | }
32 |
33 | public static async Task ExecuteSqlCommandAsync(this IUnitOfWorkAsync uow, DbContext context, string sql,
34 | CancellationToken cancellationToken, params object[] parameters)
35 | {
36 | return await context.Database.ExecuteSqlCommandAsync(sql, cancellationToken, parameters);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using NetCoreKit.Domain;
4 | using NetCoreKit.Infrastructure.EfCore.Db;
5 |
6 | namespace NetCoreKit.Infrastructure.EfCore
7 | {
8 | public static class ServiceCollectionExtensions
9 | {
10 | public static IServiceCollection AddGenericRepository(this IServiceCollection services)
11 | {
12 | services.AddScoped();
13 | services.AddScoped();
14 | return services;
15 | }
16 |
17 | public static IServiceCollection AddInMemoryDb(this IServiceCollection services)
18 | {
19 | services.AddScoped();
20 | services.AddScoped();
21 | return services;
22 | }
23 | }
24 |
25 | internal class NoOpDbConnStringFactory : IDbConnStringFactory
26 | {
27 | public string Create()
28 | {
29 | return string.Empty;
30 | }
31 | }
32 |
33 | internal class InMemoryDbContextOptionsBuilderFactory : IExtendDbContextOptionsBuilder
34 | {
35 | public DbContextOptionsBuilder Extend(
36 | DbContextOptionsBuilder optionsBuilder,
37 | IDbConnStringFactory connStringFactory,
38 | string assemblyName)
39 | {
40 | return optionsBuilder.UseInMemoryDatabase("default_db");
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.EfCore.MySql/DatabaseConnectionStringFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Microsoft.Extensions.Options;
3 | using NetCoreKit.Infrastructure.EfCore.Db;
4 |
5 | namespace NetCoreKit.Infrastructure.EfCore.MySql
6 | {
7 | public sealed class DbConnStringFactory : IDbConnStringFactory
8 | {
9 | public DbOptions DbOptions { get; }
10 |
11 | public DbConnStringFactory()
12 | {
13 | var config = ConfigurationHelper.GetConfiguration();
14 | var dbSection = config.GetSection("Features:EfCore:MySqlDb");
15 | DbOptions = new DbOptions {
16 | ConnString = dbSection["ConnString"],
17 | FQDN = dbSection["FQDN"],
18 | Database = dbSection["Database"],
19 | DbInfo = dbSection["DbInfo"],
20 | UserName = dbSection["UserName"],
21 | Password = dbSection["Password"]
22 | };
23 | }
24 |
25 | public DbConnStringFactory(IOptions options)
26 | {
27 | DbOptions = options.Value;
28 | }
29 |
30 | public string Create()
31 | {
32 | var connPattern = DbOptions.ConnString;
33 | var connConfigs = DbOptions.FQDN?.Split(':');
34 | var fqdn = connConfigs?.First();
35 | var port = connConfigs?.Except(new[] {fqdn}).First();
36 |
37 | return string.Format(
38 | connPattern,
39 | fqdn, port,
40 | DbOptions.UserName,
41 | DbOptions.Password,
42 | DbOptions.Database);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/samples/BiMonetaryApi/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "API_VERSION": "1.0",
3 | "SERVICE_VERSION": "0.0.1",
4 | "QualifiedAssemblyPattern": "NetCoreKit.Samples.*",
5 | "Hosts": {
6 | "BasePath": "/",
7 | "Externals": {
8 | "CurrentUri": "http://localhost:54408"
9 | }
10 | },
11 | "Features": {
12 | "Mongo": {
13 | "ConnString": "mongodb://127.0.0.1:27017",
14 | "Database": "BiMonetaryApi"
15 | },
16 | "ApiVersion": { "Enabled": true },
17 | "OpenApi": {
18 | "OpenApiUI": { "Enabled": true },
19 | "ApiInfo": {
20 | "Title": "BiMonetary API",
21 | "Description": "An application with Swagger, Swashbuckle, and API version.",
22 | "ContactName": "Vietnam Devs",
23 | "ContactEmail": "thangchung.onthenet@gmail.com",
24 | "TermOfService": "Shareware",
25 | "LicenseName": "MIT",
26 | "LicenseUrl": "https://github.com/cloudnative-netcore/netcorekit/blob/master/LICENSE"
27 | }
28 | },
29 | "AuthN": {
30 | "ClaimToScopeMap": { "access_cart_api": "cart_api_scope" },
31 | "Scopes": { "cart_api_scope": "Cart APIs" },
32 | "Audience": "api"
33 | },
34 | "ResponseCompression": { "Enabled": true }
35 | },
36 | "RpcClients": {
37 | "ExchangeService": "localhost:5000"
38 | },
39 | "Logging": {
40 | "IncludeScopes": false,
41 | "Debug": {
42 | "LogLevel": {
43 | "Default": "Information"
44 | }
45 | },
46 | "Console": {
47 | "LogLevel": {
48 | "Default": "Debug",
49 | "System": "Information",
50 | "Microsoft": "Information"
51 | }
52 | }
53 | },
54 | "AllowedHosts": "*"
55 | }
56 |
--------------------------------------------------------------------------------
/samples/TodoApi/v1/UseCases/UpdateTask/RequestHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Microsoft.EntityFrameworkCore;
5 | using NetCoreKit.Domain;
6 | using NetCoreKit.Infrastructure.AspNetCore.CleanArch;
7 | using NetCoreKit.Infrastructure.EfCore.Extensions;
8 | using NetCoreKit.Samples.TodoAPI.Extensions;
9 | using NetCoreKit.Samples.TodoAPI.Infrastructure.Db;
10 |
11 | namespace NetCoreKit.Samples.TodoAPI.v1.UseCases.UpdateTask
12 | {
13 | public class RequestHandler : TxRequestHandlerBase
14 | {
15 | public RequestHandler(IUnitOfWorkAsync uow, IQueryRepositoryFactory queryRepositoryFactory)
16 | : base(uow, queryRepositoryFactory)
17 | {
18 | }
19 |
20 | public override async Task Handle(UpdateTaskRequest request,
21 | CancellationToken cancellationToken)
22 | {
23 | var commandRepository = CommandFactory.RepositoryAsync();
24 | var queryRepository = QueryFactory.QueryRepository();
25 |
26 | var project = await queryRepository.GetByIdAsync(request.ProjectId, q => q.Include(x => x.Tasks), false);
27 | if (project == null) throw new Exception($"Couldn't find project#{request.ProjectId}.");
28 |
29 | project.UpdateTask(request.TaskId, request.Title, request.Order ?? 1, request.Completed ?? false);
30 | var updated = await commandRepository.UpdateAsync(project);
31 |
32 | return new UpdateTaskResponse {Result = updated.ToDto()};
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Infrastructure.AspNetCore.OpenApi/SecurityRequirementsOperationFilter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using Microsoft.AspNetCore.Authorization;
4 | using Swashbuckle.AspNetCore.Swagger;
5 | using Swashbuckle.AspNetCore.SwaggerGen;
6 |
7 | namespace NetCoreKit.Infrastructure.AspNetCore.OpenApi
8 | {
9 | public class SecurityRequirementsOperationFilter : IOperationFilter
10 | {
11 | public void Apply(Operation operation, OperationFilterContext context)
12 | {
13 | // Policy names map to scopes
14 | /*var requiredScopes = context.MethodInfo
15 | .GetCustomAttributes(true)
16 | .OfType()
17 | .Select(attr => attr.Policy)
18 | .Distinct();*/
19 |
20 | var requiredScopes = context.MethodInfo.DeclaringType
21 | ?.GetCustomAttributes(true)
22 | .Union(context.MethodInfo.GetCustomAttributes(true))
23 | .OfType()
24 | .ToList();
25 |
26 | if (requiredScopes == null || !requiredScopes.Any()) return;
27 |
28 | operation.Responses.Add("401", new Response {Description = "Unauthorized"});
29 | operation.Responses.Add("403", new Response {Description = "Forbidden"});
30 |
31 | operation.Security = new List>>
32 | {
33 | new Dictionary>
34 | {
35 | ["oauth2"] = requiredScopes.Select(attr => attr.Policy).Distinct()
36 | }
37 | };
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/samples/TodoApi/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "API_VERSION": "1.0",
3 | "SERVICE_VERSION": "0.0.1",
4 | "QualifiedAssemblyPattern": "NetCoreKit.Samples.*",
5 | "Hosts": {
6 | "BasePath": "/",
7 | "Externals": {
8 | "CurrentUri": "http://localhost:32501"
9 | }
10 | },
11 | "Features": {
12 | "EfCore": {
13 | //"SqlServerConnString": "Server=tcp:{0},{1};Database={2};User Id={3};Password={4};"
14 | "MySqlDb": {
15 | "Database": "maindb",
16 | "UserName": "root",
17 | "Password": "letmein",
18 | "DbInfo": "5.7.14-mysql",
19 | "ConnString": "server={0};port={1};uid={2};pwd={3};database={4}"
20 | }
21 | },
22 | "CleanArch": { "Enabled": true },
23 | "ApiVersion": { "Enabled": true },
24 | "OpenApi": {
25 | "OpenApiUI": { "Enabled": true },
26 | "Profiler": { "Enabled": true },
27 | "ApiInfo": {
28 | "Title": "Todo APIs",
29 | "Description": "An application with Swagger, Swashbuckle, and API versioning.",
30 | "ContactName": "Vietnam Devs",
31 | "ContactEmail": "thangchung.onthenet@gmail.com",
32 | "TermOfService": "Shareware",
33 | "LicenseName": "MIT",
34 | "LicenseUrl": "https://github.com/cloudnative-netcore/netcorekit/blob/master/LICENSE"
35 | }
36 | }
37 | },
38 | "Logging": {
39 | "IncludeScopes": false,
40 | "Debug": {
41 | "LogLevel": {
42 | "Default": "Warning"
43 | }
44 | },
45 | "Console": {
46 | "LogLevel": {
47 | "Default": "Debug",
48 | "System": "Information",
49 | "Microsoft": "Information"
50 | }
51 | }
52 | },
53 | "AllowedHosts": "*"
54 | }
55 |
--------------------------------------------------------------------------------
/src/NetCoreKit.Domain/ValueObject.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using NetCoreKit.Utils.Extensions;
4 |
5 | namespace NetCoreKit.Domain
6 | {
7 | ///
8 | /// Source: https://github.com/VaughnVernon/IDDD_Samples_NET
9 | ///
10 | public abstract class ValueObjectBase
11 | {
12 | protected abstract IEnumerable