mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-04-30 09:55:45 +08:00
Merge pull request #357 from meysamhadeli/docs/update-aspir-docs
docs/update aspir docs
This commit is contained in:
commit
44e408258f
120
README.md
120
README.md
@ -1,23 +1,20 @@
|
|||||||
|
# 🛩️ Booking Monolith
|
||||||
|
|
||||||
<div align="center" style="margin-bottom:20px">
|
<div align="center" style="margin-bottom:20px">
|
||||||
<img src="assets/logo.png" alt="booking-microservices" />
|
<div align="left">
|
||||||
<div align="center">
|
<a href="https://github.com/meysamhadeli/booking-monolith/actions/workflows/ci.yml"><img alt="build-status" src="https://github.com/meysamhadeli/booking-monolith/actions/workflows/ci.yml/badge.svg?branch=main&style=flat-square"/></a>
|
||||||
<a href="https://github.com/meysamhadeli/booking-microservices/actions/workflows/ci.yml"><img alt="ci-status" src="https://github.com/meysamhadeli/booking-microservices/actions/workflows/ci.yml/badge.svg?branch=main&style=flat-square"/></a>
|
<a href="https://github.com/meysamhadeli/booking-monolith/blob/main/LICENSE"><img alt="build-status" src="https://img.shields.io/github/license/meysamhadeli/booking-monolith?color=%234275f5&style=flat-square"/></a>
|
||||||
<a href="https://github.com/meysamhadeli/booking-microservices/blob/main/LICENSE"><img alt="build-status" src="https://img.shields.io/github/license/meysamhadeli/booking-microservices?color=%234275f5&style=flat-square"/></a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
> 🚀 **A practical microservices with the latest technologies and architecture like Vertical Slice Architecture, Event Sourcing, CQRS, DDD, gRpc, MongoDB, RabbitMq and Masstransit in .Net 9.**
|
> 🚀 **A practical Monolith architecture with the latest technologies and architectures like Vertical Slice Architecture, Event Driven Architecture, CQRS, DDD and Aspire in .Net 9.**
|
||||||
|
|
||||||
## You can find other version of this project here:
|
## You can find other version of this project here:
|
||||||
|
- [Booking with Microservices Architecture](https://github.com/meysamhadeli/booking-microservices)
|
||||||
- [Booking with Modular Monolith Architecture](https://github.com/meysamhadeli/booking-modular-monolith)
|
- [Booking with Modular Monolith Architecture](https://github.com/meysamhadeli/booking-modular-monolith)
|
||||||
- [Booking with Monolith Architecture](https://github.com/meysamhadeli/booking-monolith)
|
|
||||||
|
|
||||||
<div>
|
<a href="https://gitpod.io/#https://github.com/meysamhadeli/booking-monolith"><img alt="Open in Gitpod" src="https://gitpod.io/button/open-in-gitpod.svg"/></a>
|
||||||
<a href="https://gitpod.io/#https://github.com/meysamhadeli/booking-microservices"><img alt="Open in Gitpod" src="https://gitpod.io/button/open-in-gitpod.svg"/></a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a href='https://codespaces.new/meysamhadeli/booking-microservices?quickstart=1'><img alt='Open in GitHub Codespaces' src='https://github.com/codespaces/badge.svg'></a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
# Table of Contents
|
# Table of Contents
|
||||||
|
|
||||||
@ -26,17 +23,15 @@
|
|||||||
- [Key Features](#key-features)
|
- [Key Features](#key-features)
|
||||||
- [When to Use](#when-to-use)
|
- [When to Use](#when-to-use)
|
||||||
- [Challenges](#challenges)
|
- [Challenges](#challenges)
|
||||||
- [The Domain and Bounded Context - Service Boundary](#the-domain-and-bounded-context---service-boundary)
|
- [The Domain and Bounded Context](#the-domain-and-bounded-context)
|
||||||
- [Structure of Project](#structure-of-project)
|
- [Structure of Project](#structure-of-project)
|
||||||
- [Development Setup](#development-setup)
|
- [Development Setup](#development-setup)
|
||||||
- [Dotnet Tools Packages](#dotnet-tools-packages)
|
- [Dotnet Tools Packages](#dotnet-tools-packages)
|
||||||
- [Husky](#husky)
|
- [Husky](#husky)
|
||||||
- [Upgrade Nuget Packages](#upgrade-nuget-packages)
|
- [Upgrade Nuget Packages](#upgrade-nuget-packages)
|
||||||
- [How to Run](#how-to-run)
|
- [How to Run](#how-to-run)
|
||||||
- [Config Certificate](#config-certificate)
|
- [Config Certificate](#config-certificate)
|
||||||
- [Aspire](#aspire)
|
|
||||||
- [Docker Compose](#docker-compose)
|
- [Docker Compose](#docker-compose)
|
||||||
- [Kubernetes](#kubernetes)
|
|
||||||
- [Build](#build)
|
- [Build](#build)
|
||||||
- [Run](#run)
|
- [Run](#run)
|
||||||
- [Test](#test)
|
- [Test](#test)
|
||||||
@ -49,12 +44,11 @@
|
|||||||
|
|
||||||
- :sparkle: Using `Vertical Slice Architecture` for `architecture` level.
|
- :sparkle: Using `Vertical Slice Architecture` for `architecture` level.
|
||||||
- :sparkle: Using `Domain Driven Design (DDD)` to implement all `business logic`.
|
- :sparkle: Using `Domain Driven Design (DDD)` to implement all `business logic`.
|
||||||
- :sparkle: Using `Rabbitmq` on top of `Masstransit` for `Event Driven Architecture`.
|
|
||||||
- :sparkle: Using `gRPC` for `internal communication`.
|
|
||||||
- :sparkle: Using `CQRS` implementation with `MediatR` library.
|
- :sparkle: Using `CQRS` implementation with `MediatR` library.
|
||||||
- :sparkle: Using `Postgres` for `write side` database.
|
- :sparkle: Using `Postgres` for `write side` database.
|
||||||
|
- :sparkle: Using `InMemory Broker` on top of `Masstransit` for `Event Driven Architecture`.
|
||||||
- :sparkle: Using `MongoDB` for `read side` database.
|
- :sparkle: Using `MongoDB` for `read side` database.
|
||||||
- :sparkle: Using `Event Store` for `write side` of Booking Microservice/Module to store all `historical change` of aggregate.
|
- :sparkle: Using `Event Store` for `write side` of Booking to store all `historical change` of aggregate.
|
||||||
- :sparkle: Using `Inbox Pattern` for ensuring message idempotency for receiver and `Exactly once Delivery`.
|
- :sparkle: Using `Inbox Pattern` for ensuring message idempotency for receiver and `Exactly once Delivery`.
|
||||||
- :sparkle: Using `Outbox Pattern` for ensuring no message is lost and there is at `At Least One Delivery`.
|
- :sparkle: Using `Outbox Pattern` for ensuring no message is lost and there is at `At Least One Delivery`.
|
||||||
- :sparkle: Using `Unit Testing` for testing small units and mocking our dependencies with `Nsubstitute`.
|
- :sparkle: Using `Unit Testing` for testing small units and mocking our dependencies with `Nsubstitute`.
|
||||||
@ -68,11 +62,7 @@
|
|||||||
- :sparkle: Using `OpenTelemetry` for distributed tracing on top of `Jaeger`.
|
- :sparkle: Using `OpenTelemetry` for distributed tracing on top of `Jaeger`.
|
||||||
- :sparkle: Using `OpenTelemetry` for monitoring on top of `Prometheus` and `Grafana`.
|
- :sparkle: Using `OpenTelemetry` for monitoring on top of `Prometheus` and `Grafana`.
|
||||||
- :sparkle: Using `IdentityServer` for authentication and authorization base on `OpenID-Connect` and `OAuth2`.
|
- :sparkle: Using `IdentityServer` for authentication and authorization base on `OpenID-Connect` and `OAuth2`.
|
||||||
- :sparkle: Using `Yarp` as a microservices `gateway`.
|
- :sparkle: Using `Aspire` for `service discovery`, `observability`, and `local orchestration` of microservices.
|
||||||
- :sparkle: Using `Kubernetes` to achieve efficient `scaling` and ensure `high availability` for each of our microservices.
|
|
||||||
- :sparkle: Using `Nginx Ingress Controller` for `load balancing` between our microservices top of `Kubernetes`.
|
|
||||||
- :sparkle: Using `cert-manager` to Configure `TLS` in `kubernetes cluster`.
|
|
||||||
|
|
||||||
|
|
||||||
## Technologies - Libraries
|
## Technologies - Libraries
|
||||||
|
|
||||||
@ -95,48 +85,46 @@
|
|||||||
- ✔️ **[`Hellang.Middleware.ProblemDetails`](https://github.com/khellang/Middleware/tree/master/src/ProblemDetails)** - A middleware for handling exception in .Net Core.
|
- ✔️ **[`Hellang.Middleware.ProblemDetails`](https://github.com/khellang/Middleware/tree/master/src/ProblemDetails)** - A middleware for handling exception in .Net Core.
|
||||||
- ✔️ **[`NewId`](https://github.com/phatboyg/NewId)** - NewId can be used as an embedded unique ID generator that produces 128 bit (16 bytes) sequential IDs.
|
- ✔️ **[`NewId`](https://github.com/phatboyg/NewId)** - NewId can be used as an embedded unique ID generator that produces 128 bit (16 bytes) sequential IDs.
|
||||||
- ✔️ **[`Yarp`](https://github.com/microsoft/reverse-proxy)** - Reverse proxy toolkit for building fast proxy servers in .NET.
|
- ✔️ **[`Yarp`](https://github.com/microsoft/reverse-proxy)** - Reverse proxy toolkit for building fast proxy servers in .NET.
|
||||||
- ✔️ **[`Tye`](https://github.com/dotnet/tye)** - Developer tool that makes developing, testing, and deploying microservices and distributed applications easier.
|
|
||||||
- ✔️ **[`gRPC-dotnet`](https://github.com/grpc/grpc-dotnet)** - gRPC functionality for .NET.
|
|
||||||
- ✔️ **[`EventStore`](https://github.com/EventStore/EventStore)** - The open-source, functional database with Complex Event Processing.
|
- ✔️ **[`EventStore`](https://github.com/EventStore/EventStore)** - The open-source, functional database with Complex Event Processing.
|
||||||
- ✔️ **[`MongoDB.Driver`](https://github.com/mongodb/mongo-csharp-driver)** - .NET Driver for MongoDB.
|
- ✔️ **[`MongoDB.Driver`](https://github.com/mongodb/mongo-csharp-driver)** - .NET Driver for MongoDB.
|
||||||
- ✔️ **[`xUnit.net`](https://github.com/xunit/xunit)** - A free, open source, community-focused unit testing tool for the .NET Framework.
|
- ✔️ **[`xUnit.net`](https://github.com/xunit/xunit)** - A free, open source, community-focused unit testing tool for the .NET Framework.
|
||||||
- ✔️ **[`Respawn`](https://github.com/jbogard/Respawn)** - Respawn is a small utility to help in resetting test databases to a clean state.
|
- ✔️ **[`Respawn`](https://github.com/jbogard/Respawn)** - Respawn is a small utility to help in resetting test databases to a clean state.
|
||||||
- ✔️ **[`Testcontainers`](https://github.com/testcontainers/testcontainers-dotnet)** - Testcontainers for .NET is a library to support tests with throwaway instances of Docker containers.
|
- ✔️ **[`Testcontainers`](https://github.com/testcontainers/testcontainers-dotnet)** - Testcontainers for .NET is a library to support tests with throwaway instances of Docker containers.
|
||||||
- ✔️ **[`K6`](https://github.com/grafana/k6)** - Modern load testing for developers and testers in the DevOps era.
|
- ✔️ **[`K6`](https://github.com/grafana/k6)** - Modern load testing for developers and testers in the DevOps era.
|
||||||
|
- ✔️ **[`Aspire`](https://github.com/dotnet/aspire)** - .NET stack for building and orchestrating observable, distributed cloud-native applications.
|
||||||
|
|
||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
1. **Independent Services**: Each service is a separate project with its own database and deployment pipeline, enabling independent development and deployment.
|
1. **Single Codebase**: All components (UI, business logic, data access) are part of one project.
|
||||||
2. **Decentralized Communication**: Services communicate via APIs (REST, gRPC) or message brokers (RabbitMQ, Kafka), ensuring loose coupling and resilience.
|
2. **Tight Coupling**: Components are highly dependent on each other, making changes riskier.
|
||||||
3. **Scalability**: Services can be scaled independently based on demand, allowing efficient resource utilization.
|
3. **Simple Deployment**: The entire application is deployed as a single unit.
|
||||||
4. **Fault Tolerance**: Failures are isolated, preventing cascading failures and ensuring high availability.
|
4. **Centralized Database**: Typically uses a single database for all data storage and access.
|
||||||
5. **Technology Agnostic**: Services can use different technologies, frameworks, or databases, providing flexibility.
|
|
||||||
|
|
||||||
|
|
||||||
## When to Use
|
## When to Use
|
||||||
1. **Large and Complex Projects**: Ideal for applications with complex business logic that can be broken into smaller, manageable services.
|
1. **Small to Medium Projects**: Ideal for applications with limited complexity and scope.
|
||||||
2. **High Scalability Needs**: Suitable for applications requiring independent scaling of components.
|
2. **Rapid Development**: Suitable for projects requiring quick development and deployment.
|
||||||
3. **Fault Tolerance and High Availability**: Perfect for systems where failure isolation and uptime are critical.
|
3. **Small Teams**: Works well for small teams with limited resources.
|
||||||
4. **Distributed Teams**: Enables teams to work independently on different services.
|
4. **Low Scalability Needs**: Best for applications with predictable and low traffic.
|
||||||
5. **Frequent Updates**: Supports continuous deployment and A/B testing for individual services.
|
|
||||||
6. **Technology Diversity**: Allows the use of different technologies for different services.
|
|
||||||
|
|
||||||
|
|
||||||
## Challenges
|
## Challenges
|
||||||
- Increased complexity in management, DevOps overhead, data consistency, latency, and higher costs.
|
- Harder to maintain as the codebase grows.
|
||||||
|
- Limited scalability (scaling requires scaling the entire application).
|
||||||
|
- Difficult to adopt new technologies incrementally.
|
||||||
|
|
||||||
|
|
||||||
## The Domain And Bounded Context - Service Boundary
|
## The Domain And Bounded Context
|
||||||
|
|
||||||
- `Identity Service`: The Identity Service is a bounded context for the authentication and authorization of users using [Identity Server](https://github.com/DuendeSoftware/IdentityServer). This service is responsible for creating new users and their corresponding roles and permissions using [.Net Core Identity](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity) and Jwt authentication and authorization.
|
- `Identity`: The Identity is a bounded context for the authentication and authorization of users using [Identity Server](https://github.com/DuendeSoftware/IdentityServer). This service is responsible for creating new users and their corresponding roles and permissions using [.Net Core Identity](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity) and Jwt authentication and authorization.
|
||||||
|
|
||||||
- `Flight Service`: The Flight Service is a bounded context `CRUD` service to handle flight related operations.
|
- `Flight`: The Flight is a bounded context `CRUD` service to handle flight related operations.
|
||||||
|
|
||||||
- `Passenger Service`: The Passenger Service is a bounded context for managing passenger information, tracking activities and subscribing to get notification for out of stock products.
|
- `Passenger`: The Passenger is a bounded context for managing passenger information, tracking activities and subscribing to get notification for out of stock products.
|
||||||
|
|
||||||
- `Booking Service`: The Booking Service is a bounded context for managing all operation related to booking ticket.
|
- `Booking`: The Booking is a bounded context for managing all operation related to booking ticket.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Structure of Project
|
## Structure of Project
|
||||||
@ -178,7 +166,7 @@ dotnet tool restore
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Husky
|
### Husky
|
||||||
Here we use `husky` to handel some pre commit rules and we used `conventional commits` rules and `formatting` as pre commit rules, here in [package.json](.././package.json). of course, we can add more rules for pre commit in future. (find more about husky in the [documentation](https://typicode.github.io/husky/get-started.html))
|
Here we use `husky` to handel some pre commit rules and we used `conventional commits` rules and `formatting` as pre commit rules, here in [package.json](./package.json). of course, we can add more rules for pre commit in future. (find more about husky in the [documentation](https://typicode.github.io/husky/get-started.html))
|
||||||
We need to install `husky` package for `manage` `pre commits hooks` and also I add two packages `@commitlint/cli` and `@commitlint/config-conventional` for handling conventional commits rules in [package.json](.././package.json).
|
We need to install `husky` package for `manage` `pre commits hooks` and also I add two packages `@commitlint/cli` and `@commitlint/config-conventional` for handling conventional commits rules in [package.json](.././package.json).
|
||||||
Run the command bellow in the root of project to install all npm dependencies related to husky:
|
Run the command bellow in the root of project to install all npm dependencies related to husky:
|
||||||
|
|
||||||
@ -205,24 +193,13 @@ Run the following commands to [Config SSL](https://docs.microsoft.com/en-us/aspn
|
|||||||
dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p password
|
dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p password
|
||||||
dotnet dev-certs https --trust
|
dotnet dev-certs https --trust
|
||||||
```
|
```
|
||||||
> Note: for running this command in `powershell` use `$env:USERPROFILE` instead of `%USERPROFILE%`*
|
***Note:** for running this command in `powershell` use `$env:USERPROFILE` instead of `%USERPROFILE%`*
|
||||||
|
|
||||||
#### macOS or Linux
|
#### macOS or Linux
|
||||||
```bash
|
```bash
|
||||||
dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p $CREDENTIAL_PLACEHOLDER$
|
dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p $CREDENTIAL_PLACEHOLDER$
|
||||||
dotnet dev-certs https --trust
|
dotnet dev-certs https --trust
|
||||||
```
|
```
|
||||||
|
|
||||||
### Aspire
|
|
||||||
|
|
||||||
To run the application using the `ASPIRE App Host`, execute the following command from the solution root:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
dotnet run --project ./src/Aspire/src/AppHost
|
|
||||||
```
|
|
||||||
|
|
||||||
> Note:The `ASPIRE dashboard` will be available at `http://localhost:18888`
|
|
||||||
|
|
||||||
> ### Docker Compose
|
> ### Docker Compose
|
||||||
|
|
||||||
|
|
||||||
@ -232,41 +209,28 @@ To run this app in `Docker`, use the [docker-compose.yaml](./deployments/docker-
|
|||||||
docker-compose -f ./deployments/docker-compose/docker-compose.yaml up -d
|
docker-compose -f ./deployments/docker-compose/docker-compose.yaml up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
> ### Kubernetes
|
|
||||||
To `configure TLS` in the `Kubernetes cluster`, we need to install `cert-manager` based on the [docs](https://cert-manager.io/docs/installation) and run the following commands to apply TLS in our application. Here, we use [Let's Encrypt](https://letsencrypt.org/) to encrypt our certificate.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl apply -f ./deployments/kubernetes/booking-cert-manager.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
To apply all necessary `deployments`, `pods`, `services`, `ingress`, and `config maps`, please run the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl apply -f ./deployments/kubernetes/booking-microservices.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
> ### Build
|
> ### Build
|
||||||
To `build` all microservices, run this command in the `root` of the project:
|
To `build` monolith app, run this command in the `root` of the project:
|
||||||
```bash
|
```bash
|
||||||
dotnet build
|
dotnet build
|
||||||
```
|
```
|
||||||
|
|
||||||
> ### Run
|
> ### Run
|
||||||
To `run` each microservice, run this command in the root of the `Api` folder of each microservice where the `csproj` file is located:
|
To `run` monolith app, run this command in the root of the `Api` folder:
|
||||||
```bash
|
```bash
|
||||||
dotnet run
|
dotnet run
|
||||||
```
|
```
|
||||||
|
|
||||||
> ### Test
|
> ### Test
|
||||||
|
|
||||||
To `test` all microservices, run this command in the `root` of the project:
|
To `test` monolith app, run this command in the `root` of the project:
|
||||||
```bash
|
```bash
|
||||||
dotnet test
|
dotnet test
|
||||||
```
|
```
|
||||||
|
|
||||||
> ### Documentation Apis
|
> ### Documentation Apis
|
||||||
|
|
||||||
Each microservice provides `API documentation` and navigate to `/swagger` for `Swagger OpenAPI` or `/scalar/v1` for `Scalar OpenAPI` to visit list of endpoints.
|
For checking `API documentation`, navigate to `/swagger` for `Swagger OpenAPI` or `/scalar/v1` for `Scalar OpenAPI` to visit list of endpoints.
|
||||||
|
|
||||||
As part of API testing, I created the [booking.rest](./booking.rest) file which can be run with the [REST Client](https://github.com/Huachao/vscode-restclient) `VSCode plugin`.
|
As part of API testing, I created the [booking.rest](./booking.rest) file which can be run with the [REST Client](https://github.com/Huachao/vscode-restclient) `VSCode plugin`.
|
||||||
|
|
||||||
@ -280,7 +244,7 @@ Thanks a bunch for supporting me!
|
|||||||
|
|
||||||
## Contribution
|
## Contribution
|
||||||
|
|
||||||
Thanks to all [contributors](https://github.com/meysamhadeli/booking-microservices/graphs/contributors), you're awesome and this wouldn't be possible without you! The goal is to build a categorized, community-driven collection of very well-known resources.
|
Thanks to all [contributors](https://github.com/meysamhadeli/booking-monolith/graphs/contributors), you're awesome and this wouldn't be possible without you! The goal is to build a categorized, community-driven collection of very well-known resources.
|
||||||
|
|
||||||
Please follow this [contribution guideline](./CONTRIBUTION.md) to submit a pull request or create the issue.
|
Please follow this [contribution guideline](./CONTRIBUTION.md) to submit a pull request or create the issue.
|
||||||
|
|
||||||
@ -293,4 +257,4 @@ Please follow this [contribution guideline](./CONTRIBUTION.md) to submit a pull
|
|||||||
- [https://github.com/pdevito3/MessageBusTestingInMemHarness](https://github.com/pdevito3/MessageBusTestingInMemHarness)
|
- [https://github.com/pdevito3/MessageBusTestingInMemHarness](https://github.com/pdevito3/MessageBusTestingInMemHarness)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
This project is made available under the MIT license. See [LICENSE](https://github.com/meysamhadeli/booking-microservices/blob/main/LICENSE) for details.
|
This project is made available under the MIT license. See [LICENSE](https://github.com/meysamhadeli/booking-monolith/blob/main/LICENSE) for details.
|
||||||
|
|||||||
@ -29,4 +29,4 @@ app.UseEndpoints(endpoints =>
|
|||||||
|
|
||||||
app.MapGet("/", x => x.Response.WriteAsync(appOptions.Name));
|
app.MapGet("/", x => x.Response.WriteAsync(appOptions.Name));
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
@ -213,4 +213,4 @@ var gateway = builder.AddProject<Projects.ApiGateway>("api-gateway")
|
|||||||
.WithHttpEndpoint(port: 5001, name: "gateway-http")
|
.WithHttpEndpoint(port: 5001, name: "gateway-http")
|
||||||
.WithHttpsEndpoint(port: 5000, name: "gateway-https");
|
.WithHttpsEndpoint(port: 5000, name: "gateway-https");
|
||||||
|
|
||||||
builder.Build().Run();
|
builder.Build().Run();
|
||||||
@ -47,4 +47,4 @@ public class CachingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest,
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,4 +4,4 @@ public interface ICacheRequest
|
|||||||
{
|
{
|
||||||
string CacheKey { get; }
|
string CacheKey { get; }
|
||||||
DateTime? AbsoluteExpirationRelativeToNow { get; }
|
DateTime? AbsoluteExpirationRelativeToNow { get; }
|
||||||
}
|
}
|
||||||
@ -4,4 +4,4 @@ namespace BuildingBlocks.Caching
|
|||||||
{
|
{
|
||||||
string CacheKey { get; }
|
string CacheKey { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,4 +36,4 @@ namespace BuildingBlocks.Caching
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7,4 +7,4 @@ public static class IdentityConstant
|
|||||||
public const string Admin = "admin";
|
public const string Admin = "admin";
|
||||||
public const string User = "user";
|
public const string User = "user";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,4 +8,4 @@ public record FlightDeleted(Guid Id) : IIntegrationEvent;
|
|||||||
public record AircraftCreated(Guid Id) : IIntegrationEvent;
|
public record AircraftCreated(Guid Id) : IIntegrationEvent;
|
||||||
public record AirportCreated(Guid Id) : IIntegrationEvent;
|
public record AirportCreated(Guid Id) : IIntegrationEvent;
|
||||||
public record SeatCreated(Guid Id) : IIntegrationEvent;
|
public record SeatCreated(Guid Id) : IIntegrationEvent;
|
||||||
public record SeatReserved(Guid Id) : IIntegrationEvent;
|
public record SeatReserved(Guid Id) : IIntegrationEvent;
|
||||||
@ -2,4 +2,4 @@ using BuildingBlocks.Core.Event;
|
|||||||
|
|
||||||
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
||||||
|
|
||||||
public record UserCreated(Guid Id, string Name, string PassportNumber) : IIntegrationEvent;
|
public record UserCreated(Guid Id, string Name, string PassportNumber) : IIntegrationEvent;
|
||||||
@ -3,4 +3,4 @@ using BuildingBlocks.Core.Event;
|
|||||||
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
||||||
|
|
||||||
public record PassengerRegistrationCompleted(Guid Id) : IIntegrationEvent;
|
public record PassengerRegistrationCompleted(Guid Id) : IIntegrationEvent;
|
||||||
public record PassengerCreated(Guid Id) : IIntegrationEvent;
|
public record PassengerCreated(Guid Id) : IIntegrationEvent;
|
||||||
@ -2,4 +2,4 @@ using BuildingBlocks.Core.Event;
|
|||||||
|
|
||||||
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
||||||
|
|
||||||
public record BookingCreated(Guid Id) : IIntegrationEvent;
|
public record BookingCreated(Guid Id) : IIntegrationEvent;
|
||||||
@ -9,4 +9,4 @@ public interface ICommand : ICommand<Unit>
|
|||||||
public interface ICommand<out T> : IRequest<T>
|
public interface ICommand<out T> : IRequest<T>
|
||||||
where T : notnull
|
where T : notnull
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -11,4 +11,4 @@ public interface ICommandHandler<in TCommand, TResponse> : IRequestHandler<TComm
|
|||||||
where TCommand : ICommand<TResponse>
|
where TCommand : ICommand<TResponse>
|
||||||
where TResponse : notnull
|
where TResponse : notnull
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -5,4 +5,4 @@ namespace BuildingBlocks.Core.CQRS;
|
|||||||
public interface IQuery<out T> : IRequest<T>
|
public interface IQuery<out T> : IRequest<T>
|
||||||
where T : notnull
|
where T : notnull
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -6,4 +6,4 @@ public interface IQueryHandler<in TQuery, TResponse> : IRequestHandler<TQuery, T
|
|||||||
where TQuery : IQuery<TResponse>
|
where TQuery : IQuery<TResponse>
|
||||||
where TResponse : notnull
|
where TResponse : notnull
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -34,4 +34,4 @@ public class CompositeEventMapper : IEventMapper
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,4 +6,4 @@ public enum EventType
|
|||||||
DomainEvent = 1,
|
DomainEvent = 1,
|
||||||
IntegrationEvent = 2,
|
IntegrationEvent = 2,
|
||||||
InternalCommand = 4
|
InternalCommand = 4
|
||||||
}
|
}
|
||||||
@ -2,4 +2,4 @@ namespace BuildingBlocks.Core.Event;
|
|||||||
|
|
||||||
public interface IDomainEvent : IEvent
|
public interface IDomainEvent : IEvent
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -9,4 +9,4 @@ public interface IEvent : INotification
|
|||||||
Guid EventId => NewId.NextGuid();
|
Guid EventId => NewId.NextGuid();
|
||||||
public DateTime OccurredOn => DateTime.Now;
|
public DateTime OccurredOn => DateTime.Now;
|
||||||
public string EventType => GetType().AssemblyQualifiedName;
|
public string EventType => GetType().AssemblyQualifiedName;
|
||||||
}
|
}
|
||||||
@ -2,4 +2,4 @@ namespace BuildingBlocks.Core.Event;
|
|||||||
|
|
||||||
public interface IHaveIntegrationEvent
|
public interface IHaveIntegrationEvent
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -5,4 +5,4 @@ namespace BuildingBlocks.Core.Event;
|
|||||||
[ExcludeFromTopology]
|
[ExcludeFromTopology]
|
||||||
public interface IIntegrationEvent : IEvent
|
public interface IIntegrationEvent : IEvent
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -2,4 +2,4 @@ namespace BuildingBlocks.Core.Event;
|
|||||||
|
|
||||||
public interface IInternalCommand : IEvent
|
public interface IInternalCommand : IEvent
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -2,4 +2,4 @@ using BuildingBlocks.Core.CQRS;
|
|||||||
|
|
||||||
namespace BuildingBlocks.Core.Event;
|
namespace BuildingBlocks.Core.Event;
|
||||||
|
|
||||||
public record InternalCommand : IInternalCommand, ICommand;
|
public record InternalCommand : IInternalCommand, ICommand;
|
||||||
@ -23,4 +23,4 @@ public class MessageEnvelope<TMessage> : MessageEnvelope
|
|||||||
}
|
}
|
||||||
|
|
||||||
public new TMessage? Message { get; }
|
public new TMessage? Message { get; }
|
||||||
}
|
}
|
||||||
@ -152,4 +152,4 @@ public sealed class EventDispatcher(
|
|||||||
|
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,4 +8,4 @@ public interface IEventDispatcher
|
|||||||
where T : IEvent;
|
where T : IEvent;
|
||||||
public Task SendAsync<T>(T @event, Type type = null, CancellationToken cancellationToken = default)
|
public Task SendAsync<T>(T @event, Type type = null, CancellationToken cancellationToken = default)
|
||||||
where T : IEvent;
|
where T : IEvent;
|
||||||
}
|
}
|
||||||
@ -6,4 +6,4 @@ public interface IEventMapper
|
|||||||
{
|
{
|
||||||
IIntegrationEvent? MapToIntegrationEvent(IDomainEvent @event);
|
IIntegrationEvent? MapToIntegrationEvent(IDomainEvent @event);
|
||||||
IInternalCommand? MapToInternalCommand(IDomainEvent @event);
|
IInternalCommand? MapToInternalCommand(IDomainEvent @event);
|
||||||
}
|
}
|
||||||
@ -3,4 +3,4 @@ using BuildingBlocks.Core.Event;
|
|||||||
namespace BuildingBlocks.Core;
|
namespace BuildingBlocks.Core;
|
||||||
|
|
||||||
public record IntegrationEventWrapper<TDomainEventType>(TDomainEventType DomainEvent) : IIntegrationEvent
|
public record IntegrationEventWrapper<TDomainEventType>(TDomainEventType DomainEvent) : IIntegrationEvent
|
||||||
where TDomainEventType : IDomainEvent;
|
where TDomainEventType : IDomainEvent;
|
||||||
@ -20,4 +20,4 @@ public abstract record Aggregate<TId> : Entity<TId>, IAggregate<TId>
|
|||||||
|
|
||||||
return dequeuedEvents;
|
return dequeuedEvents;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,4 +9,4 @@ public abstract record Entity<T> : IEntity<T>
|
|||||||
public long? LastModifiedBy { get; set; }
|
public long? LastModifiedBy { get; set; }
|
||||||
public bool IsDeleted { get; set; }
|
public bool IsDeleted { get; set; }
|
||||||
public long Version { get; set; }
|
public long Version { get; set; }
|
||||||
}
|
}
|
||||||
@ -10,4 +10,4 @@ public interface IAggregate : IEntity
|
|||||||
{
|
{
|
||||||
IReadOnlyList<IDomainEvent> DomainEvents { get; }
|
IReadOnlyList<IDomainEvent> DomainEvents { get; }
|
||||||
IEvent[] ClearDomainEvents();
|
IEvent[] ClearDomainEvents();
|
||||||
}
|
}
|
||||||
@ -12,4 +12,4 @@ public interface IEntity : IVersion
|
|||||||
public DateTime? LastModified { get; set; }
|
public DateTime? LastModified { get; set; }
|
||||||
public long? LastModifiedBy { get; set; }
|
public long? LastModifiedBy { get; set; }
|
||||||
public bool IsDeleted { get; set; }
|
public bool IsDeleted { get; set; }
|
||||||
}
|
}
|
||||||
@ -4,4 +4,4 @@ namespace BuildingBlocks.Core.Model;
|
|||||||
public interface IVersion
|
public interface IVersion
|
||||||
{
|
{
|
||||||
long Version { get; set; }
|
long Version { get; set; }
|
||||||
}
|
}
|
||||||
@ -33,4 +33,4 @@ public static class Extensions
|
|||||||
|
|
||||||
return PageList<TEntity>.Create(items.AsReadOnly(), pageRequest.PageNumber, pageRequest.PageSize, total);
|
return PageList<TEntity>.Create(items.AsReadOnly(), pageRequest.PageNumber, pageRequest.PageSize, total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,4 +13,4 @@ public interface IPageList<T>
|
|||||||
int TotalCount { get; init; }
|
int TotalCount { get; init; }
|
||||||
int PageNumber { get; init; }
|
int PageNumber { get; init; }
|
||||||
int PageSize { get; init; }
|
int PageSize { get; init; }
|
||||||
}
|
}
|
||||||
@ -4,4 +4,4 @@ using MediatR;
|
|||||||
|
|
||||||
public interface IPageQuery<out TResponse> : IPageRequest, IRequest<TResponse>
|
public interface IPageQuery<out TResponse> : IPageRequest, IRequest<TResponse>
|
||||||
where TResponse : class
|
where TResponse : class
|
||||||
{ }
|
{ }
|
||||||
@ -6,4 +6,4 @@ public interface IPageRequest
|
|||||||
int PageSize { get; init; }
|
int PageSize { get; init; }
|
||||||
string? Filters { get; init; }
|
string? Filters { get; init; }
|
||||||
string? SortOrder { get; init; }
|
string? SortOrder { get; init; }
|
||||||
}
|
}
|
||||||
@ -16,4 +16,4 @@ public record PageList<T>(IReadOnlyList<T> Items, int PageNumber, int PageSize,
|
|||||||
{
|
{
|
||||||
return new PageList<T>(items, pageNumber, pageSize, totalItems);
|
return new PageList<T>(items, pageNumber, pageSize, totalItems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,4 +178,4 @@ public abstract class AppDbContextBase : DbContext, IDbContext
|
|||||||
throw new System.Exception("try for find IAggregate", ex);
|
throw new System.Exception("try for find IAggregate", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,4 +57,4 @@ namespace BuildingBlocks.EFCore
|
|||||||
return CreateNewInstance(options);
|
return CreateNewInstance(options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,4 +78,4 @@ where TResponse : notnull
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,4 +138,4 @@ public static class Extensions
|
|||||||
|
|
||||||
await seedersManager.ExecuteSeedAsync();
|
await seedersManager.ExecuteSeedAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,4 +9,4 @@ namespace BuildingBlocks.EFCore
|
|||||||
{
|
{
|
||||||
Task SeedAllAsync();
|
Task SeedAllAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,4 +15,4 @@ public interface IDbContext
|
|||||||
Task RollbackTransactionAsync(CancellationToken cancellationToken = default);
|
Task RollbackTransactionAsync(CancellationToken cancellationToken = default);
|
||||||
IExecutionStrategy CreateExecutionStrategy();
|
IExecutionStrategy CreateExecutionStrategy();
|
||||||
Task ExecuteTransactionalAsync(CancellationToken cancellationToken = default);
|
Task ExecuteTransactionalAsync(CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
@ -4,4 +4,4 @@ public interface ISeedManager
|
|||||||
{
|
{
|
||||||
Task ExecuteSeedAsync();
|
Task ExecuteSeedAsync();
|
||||||
Task ExecuteTestSeedAsync();
|
Task ExecuteTestSeedAsync();
|
||||||
}
|
}
|
||||||
@ -3,4 +3,4 @@ namespace BuildingBlocks.EFCore;
|
|||||||
public class PostgresOptions
|
public class PostgresOptions
|
||||||
{
|
{
|
||||||
public string ConnectionString { get; set; }
|
public string ConnectionString { get; set; }
|
||||||
}
|
}
|
||||||
@ -39,4 +39,4 @@ public class SeedManager(
|
|||||||
logger.LogInformation("Seed {SeederName} is completed.", testSeeder.GetType().Name);
|
logger.LogInformation("Seed {SeederName} is completed.", testSeeder.GetType().Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -25,4 +25,4 @@ public class BackgroundWorker : BackgroundService
|
|||||||
await perform(stoppingToken);
|
await perform(stoppingToken);
|
||||||
logger.LogInformation("Background worker stopped");
|
logger.LogInformation("Background worker stopped");
|
||||||
}, stoppingToken);
|
}, stoppingToken);
|
||||||
}
|
}
|
||||||
@ -90,4 +90,4 @@ public static class EventStoreDBConfigExtensions
|
|||||||
.AsImplementedInterfaces()
|
.AsImplementedInterfaces()
|
||||||
.WithTransientLifetime());
|
.WithTransientLifetime());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -24,5 +24,4 @@ namespace BuildingBlocks.EventStoreDB.Events
|
|||||||
|
|
||||||
public virtual void When(object @event) { }
|
public virtual void When(object @event) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,4 +36,4 @@ public static class AggregateStreamExtensions
|
|||||||
|
|
||||||
return aggregate;
|
return aggregate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,4 +40,4 @@ public class EventTypeMapper
|
|||||||
|
|
||||||
return type;
|
return type;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -12,4 +12,4 @@ namespace BuildingBlocks.EventStoreDB.Events
|
|||||||
public interface IAggregateEventSourcing<T> : IAggregateEventSourcing, IEntity<T>
|
public interface IAggregateEventSourcing<T> : IAggregateEventSourcing, IEntity<T>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,4 +6,4 @@ namespace BuildingBlocks.EventStoreDB.Events;
|
|||||||
public interface IEventHandler<in TEvent> : INotificationHandler<TEvent>
|
public interface IEventHandler<in TEvent> : INotificationHandler<TEvent>
|
||||||
where TEvent : IEvent
|
where TEvent : IEvent
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -4,4 +4,4 @@ namespace BuildingBlocks.EventStoreDB.Events;
|
|||||||
|
|
||||||
public interface IExternalEvent : IEvent
|
public interface IExternalEvent : IEvent
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -3,4 +3,4 @@ namespace BuildingBlocks.EventStoreDB.Events;
|
|||||||
public interface IProjection
|
public interface IProjection
|
||||||
{
|
{
|
||||||
void When(object @event);
|
void When(object @event);
|
||||||
}
|
}
|
||||||
@ -26,5 +26,4 @@ public class StreamEvent<T> : StreamEvent where T : notnull
|
|||||||
public StreamEvent(T data, EventMetadata metadata) : base(data, metadata)
|
public StreamEvent(T data, EventMetadata metadata) : base(data, metadata)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,4 +16,4 @@ public static class StreamEventExtensions
|
|||||||
var type = typeof(StreamEvent<>).MakeGenericType(eventData.GetType());
|
var type = typeof(StreamEvent<>).MakeGenericType(eventData.GetType());
|
||||||
return (StreamEvent)Activator.CreateInstance(type, eventData, metaData)!;
|
return (StreamEvent)Activator.CreateInstance(type, eventData, metaData)!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -25,4 +25,4 @@ public class StreamNameMapper
|
|||||||
return $"{tenantPrefix}{streamType.Name}-{aggregateId}";
|
return $"{tenantPrefix}{streamType.Name}-{aggregateId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -23,4 +23,4 @@ public static class Extensions
|
|||||||
.AddEventStoreDB(configuration)
|
.AddEventStoreDB(configuration)
|
||||||
.AddProjections(assembliesToScan);
|
.AddProjections(assembliesToScan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7,4 +7,4 @@ public interface IProjectionProcessor
|
|||||||
{
|
{
|
||||||
Task ProcessEventAsync<T>(StreamEvent<T> streamEvent, CancellationToken cancellationToken = default)
|
Task ProcessEventAsync<T>(StreamEvent<T> streamEvent, CancellationToken cancellationToken = default)
|
||||||
where T : INotification;
|
where T : INotification;
|
||||||
}
|
}
|
||||||
@ -9,4 +9,4 @@ public interface IProjectionPublisher
|
|||||||
where T : INotification;
|
where T : INotification;
|
||||||
|
|
||||||
Task PublishAsync(StreamEvent streamEvent, CancellationToken cancellationToken = default);
|
Task PublishAsync(StreamEvent streamEvent, CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
@ -36,4 +36,4 @@ public class ProjectionPublisher : IProjectionPublisher
|
|||||||
return (Task)method
|
return (Task)method
|
||||||
.Invoke(this, new object[] { streamEvent, cancellationToken })!;
|
.Invoke(this, new object[] { streamEvent, cancellationToken })!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,4 +71,4 @@ public class EventStoreDBRepository<T> : IEventStoreDBRepository<T> where T : cl
|
|||||||
return events
|
return events
|
||||||
.Select(EventStoreDBSerializer.ToJsonEventData);
|
.Select(EventStoreDBSerializer.ToJsonEventData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,4 +30,4 @@ public static class RepositoryExtensions
|
|||||||
|
|
||||||
return await repository.Update(entity, expectedVersion, cancellationToken);
|
return await repository.Update(entity, expectedVersion, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,4 +36,4 @@ public static class EventStoreDBSerializer
|
|||||||
Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(@event)),
|
Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(@event)),
|
||||||
Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { }))
|
Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { }))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -78,4 +78,4 @@ public static class JsonObjectContractProvider
|
|||||||
.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||||
.OrderByDescending(e => e.GetParameters().Length)
|
.OrderByDescending(e => e.GetParameters().Length)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
}
|
}
|
||||||
@ -12,4 +12,4 @@ public class NonDefaultConstructorContractResolver : DefaultContractResolver
|
|||||||
base.CreateConstructorParameters
|
base.CreateConstructorParameters
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,4 +65,4 @@ public static class SerializationExtensions
|
|||||||
{
|
{
|
||||||
return new StringContent(obj.ToJson(), Encoding.UTF8, "application/json");
|
return new StringContent(obj.ToJson(), Encoding.UTF8, "application/json");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,4 +73,4 @@ public class EventStoreDBSubscriptionCheckpointRepository : ISubscriptionCheckpo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCheckpointStreamName(string subscriptionId) => $"checkpoint_{subscriptionId}";
|
private static string GetCheckpointStreamName(string subscriptionId) => $"checkpoint_{subscriptionId}";
|
||||||
}
|
}
|
||||||
@ -188,4 +188,4 @@ public class EventStoreDBSubscriptionToAll
|
|||||||
logger.LogInformation("Checkpoint event - ignoring");
|
logger.LogInformation("Checkpoint event - ignoring");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,4 +5,4 @@ public interface ISubscriptionCheckpointRepository
|
|||||||
ValueTask<ulong?> Load(string subscriptionId, CancellationToken ct);
|
ValueTask<ulong?> Load(string subscriptionId, CancellationToken ct);
|
||||||
|
|
||||||
ValueTask Store(string subscriptionId, ulong position, CancellationToken ct);
|
ValueTask Store(string subscriptionId, ulong position, CancellationToken ct);
|
||||||
}
|
}
|
||||||
@ -17,4 +17,4 @@ public class InMemorySubscriptionCheckpointRepository : ISubscriptionCheckpointR
|
|||||||
|
|
||||||
return ValueTask.CompletedTask;
|
return ValueTask.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10,4 +10,4 @@ public class AggregateNotFoundException : System.Exception
|
|||||||
{
|
{
|
||||||
return new AggregateNotFoundException(typeof(T).Name, id);
|
return new AggregateNotFoundException(typeof(T).Name, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11,4 +11,4 @@ public class AppException : CustomException
|
|||||||
public AppException(string message, System.Exception innerException, HttpStatusCode statusCode = HttpStatusCode.BadRequest, int? code = null) : base(message, innerException, statusCode, code)
|
public AppException(string message, System.Exception innerException, HttpStatusCode statusCode = HttpStatusCode.BadRequest, int? code = null) : base(message, innerException, statusCode, code)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10,4 +10,4 @@ namespace BuildingBlocks.Exception
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,4 +8,4 @@ namespace BuildingBlocks.Exception
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,4 +34,4 @@ public class CustomException : System.Exception
|
|||||||
public HttpStatusCode StatusCode { get; }
|
public HttpStatusCode StatusCode { get; }
|
||||||
|
|
||||||
public int? Code { get; }
|
public int? Code { get; }
|
||||||
}
|
}
|
||||||
@ -13,4 +13,4 @@ namespace SmartCharging.Infrastructure.Exceptions
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20,4 +20,4 @@ public class GrpcExceptionInterceptor : Interceptor
|
|||||||
throw new RpcException(new Status(StatusCode.Internal, exception.Message));
|
throw new RpcException(new Status(StatusCode.Internal, exception.Message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14,4 +14,4 @@ namespace BuildingBlocks.Exception
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,4 +8,4 @@ namespace BuildingBlocks.Exception
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,4 +9,4 @@ public class ProblemDetailsWithCode : ProblemDetails
|
|||||||
{
|
{
|
||||||
[JsonPropertyName("code")]
|
[JsonPropertyName("code")]
|
||||||
public int? Code { get; set; }
|
public int? Code { get; set; }
|
||||||
}
|
}
|
||||||
@ -8,4 +8,4 @@ namespace BuildingBlocks.Exception
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,4 +87,4 @@ public static class Extensions
|
|||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,4 +3,4 @@ namespace BuildingBlocks.HealthCheck;
|
|||||||
public class HealthOptions
|
public class HealthOptions
|
||||||
{
|
{
|
||||||
public bool Enabled { get; set; } = true;
|
public bool Enabled { get; set; } = true;
|
||||||
}
|
}
|
||||||
@ -21,4 +21,4 @@ public class AuthHeaderHandler : DelegatingHandler
|
|||||||
|
|
||||||
return base.SendAsync(request, cancellationToken);
|
return base.SendAsync(request, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,4 +74,4 @@ namespace BuildingBlocks.Jwt
|
|||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,4 +37,4 @@ public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest,
|
|||||||
_logger.LogInformation("[{Prefix}] Handled {X-RequestData}", prefix, typeof(TRequest).Name);
|
_logger.LogInformation("[{Prefix}] Handled {X-RequestData}", prefix, typeof(TRequest).Name);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -16,4 +16,4 @@ public static class Extensions
|
|||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35,4 +35,4 @@ public class ConsumeFilter<T> : IFilter<ConsumeContext<T>>
|
|||||||
public void Probe(ProbeContext context)
|
public void Probe(ProbeContext context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,4 +117,4 @@ public static class Extensions
|
|||||||
.Ignore<
|
.Ignore<
|
||||||
ValidationException>(); // don't retry if we have invalid data and message goes to _error queue masstransit
|
ValidationException>(); // don't retry if we have invalid data and message goes to _error queue masstransit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7,4 +7,4 @@ public class RabbitMqOptions
|
|||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
public ushort? Port { get; set; }
|
public ushort? Port { get; set; }
|
||||||
}
|
}
|
||||||
@ -4,4 +4,4 @@ public enum TransportType
|
|||||||
{
|
{
|
||||||
RabbitMq,
|
RabbitMq,
|
||||||
InMemory
|
InMemory
|
||||||
}
|
}
|
||||||
@ -49,4 +49,4 @@ namespace BuildingBlocks.Mongo
|
|||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10,4 +10,4 @@ public interface IMongoDbContext : IDisposable
|
|||||||
Task CommitTransactionAsync(CancellationToken cancellationToken = default);
|
Task CommitTransactionAsync(CancellationToken cancellationToken = default);
|
||||||
Task RollbackTransaction(CancellationToken cancellationToken = default);
|
Task RollbackTransaction(CancellationToken cancellationToken = default);
|
||||||
void AddCommand(Func<Task> func);
|
void AddCommand(Func<Task> func);
|
||||||
}
|
}
|
||||||
@ -5,4 +5,4 @@ namespace BuildingBlocks.Mongo;
|
|||||||
public interface IMongoRepository<TEntity, in TId> : IRepository<TEntity, TId>
|
public interface IMongoRepository<TEntity, in TId> : IRepository<TEntity, TId>
|
||||||
where TEntity : class, IAggregate<TId>
|
where TEntity : class, IAggregate<TId>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -2,4 +2,4 @@ namespace BuildingBlocks.Mongo;
|
|||||||
|
|
||||||
public interface IMongoUnitOfWork<out TContext> : IUnitOfWork<TContext> where TContext : class, IMongoDbContext
|
public interface IMongoUnitOfWork<out TContext> : IUnitOfWork<TContext> where TContext : class, IMongoDbContext
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -46,4 +46,4 @@ public interface IRepository<TEntity, in TId> :
|
|||||||
public interface IRepository<TEntity> : IRepository<TEntity, long>
|
public interface IRepository<TEntity> : IRepository<TEntity, long>
|
||||||
where TEntity : class, IAggregate<long>
|
where TEntity : class, IAggregate<long>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user