├── .gitattributes
├── .github
└── workflows
│ ├── Allegro.Extensions.ApplicationInsights.ci.yml
│ ├── Allegro.Extensions.ApplicationInsights.publish.yml
│ ├── Allegro.Extensions.AspNetCore.ci.yml
│ ├── Allegro.Extensions.AspNetCore.publish.yml
│ ├── Allegro.Extensions.Cqrs.Abstractions.ci.yml
│ ├── Allegro.Extensions.Cqrs.Abstractions.publish.yml
│ ├── Allegro.Extensions.Cqrs.FluentValidations.ci.yml
│ ├── Allegro.Extensions.Cqrs.FluentValidations.publish.yml
│ ├── Allegro.Extensions.Cqrs.ci.yml
│ ├── Allegro.Extensions.Cqrs.publish.yml
│ ├── Allegro.Extensions.Dapper.Postgres.ci.yml
│ ├── Allegro.Extensions.Dapper.Postgres.publish.yml
│ ├── Allegro.Extensions.Dapper.ci.yml
│ ├── Allegro.Extensions.Dapper.publish.yml
│ ├── Allegro.Extensions.DependencyCall.ci.yml
│ ├── Allegro.Extensions.DependencyCall.publish.yml
│ ├── Allegro.Extensions.Financials.ci.yml
│ ├── Allegro.Extensions.Financials.publish.yml
│ ├── Allegro.Extensions.Globalization.ci.yml
│ ├── Allegro.Extensions.Globalization.publish.yml
│ ├── Allegro.Extensions.Identifiers.Abstractions.ci.yml
│ ├── Allegro.Extensions.Identifiers.Abstractions.publish.yml
│ ├── Allegro.Extensions.Identifiers.AspNetCore.ci.yml
│ ├── Allegro.Extensions.Identifiers.AspNetCore.publish.yml
│ ├── Allegro.Extensions.NullableReferenceTypes.ci.yml
│ ├── Allegro.Extensions.NullableReferenceTypes.publish.yml
│ ├── Allegro.Extensions.RateLimiting.ci.yml
│ ├── Allegro.Extensions.RateLimiting.publish.yml
│ ├── Allegro.Extensions.Serialization.ci.yml
│ ├── Allegro.Extensions.Serialization.publish.yml
│ ├── Allegro.Extensions.Validators.ci.yml
│ ├── Allegro.Extensions.Validators.publish.yml
│ └── template.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── ap-catalog-info.yaml
├── docs
└── index.md
├── global.json
├── mkdocs.yml
└── src
├── .editorconfig
├── Allegro.Extensions.ApplicationInsights
├── Allegro.Extensions.ApplicationInsights.AspNetCore.UnitTests
│ ├── .editorconfig
│ ├── AdaptiveSamplingConfigurationTests.cs
│ ├── Allegro.Extensions.ApplicationInsights.AspNetCore.UnitTests.csproj
│ ├── FilterTests.cs
│ └── SamplingFilterTests.cs
├── Allegro.Extensions.ApplicationInsights.AspNetCore
│ ├── Allegro.Extensions.ApplicationInsights.AspNetCore.csproj
│ ├── CloudApplicationInfo
│ │ ├── TelemetryCloudApplicationInfo.cs
│ │ └── TelemetryCloudApplicationInfoTelemetryInitializer.cs
│ ├── FlushAppInsightsHostedService.cs
│ ├── InternalsVisibleTo.cs
│ ├── SamplingConfig
│ │ ├── AdaptiveSamplingConfig.cs
│ │ ├── PrintSamplingConfigurationService.cs
│ │ ├── SamplingConfig.cs
│ │ └── SamplingMode.cs
│ ├── SamplingExclusions
│ │ ├── DependencyForFilter.cs
│ │ ├── ExcludeFromSamplingTelemetryConfig.cs
│ │ ├── ExcludeFromSamplingTelemetryInitializer.cs
│ │ └── RequestForFilter.cs
│ ├── SendConfig.cs
│ ├── StartupExtensions.cs
│ ├── StartupLogger
│ │ └── StartupLogger.cs
│ └── TelemetryContext
│ │ ├── TelemetryContext.cs
│ │ ├── TelemetryContextInitializer.cs
│ │ └── TelemetryContextMiddleware.cs
├── Allegro.Extensions.ApplicationInsights.Demo.UnitTests
│ ├── .editorconfig
│ ├── Allegro.Extensions.ApplicationInsights.Demo.UnitTests.csproj
│ ├── ExcludeFromSamplingTelemetryInitializerRulesTests.cs
│ └── SamplingFilterTests.cs
├── Allegro.Extensions.ApplicationInsights.Demo
│ ├── Allegro.Extensions.ApplicationInsights.Demo.csproj
│ ├── Controllers
│ │ └── WeatherForecastController.cs
│ ├── CustomDependencyForFilter.cs
│ ├── CustomTelemetryCloudApplicationInfo.cs
│ ├── InternalsVisibleTo.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── appsettings.Development.json
│ └── appsettings.json
├── Allegro.Extensions.ApplicationInsights.Prometheus.UnitTests
│ ├── .editorconfig
│ ├── Allegro.Extensions.ApplicationInsights.Prometheus.UnitTests.csproj
│ └── ApplicationInsightsToPrometheusMetricsInitializerTests.cs
├── Allegro.Extensions.ApplicationInsights.Prometheus
│ ├── Allegro.Extensions.ApplicationInsights.Prometheus.csproj
│ ├── ApplicationInsightsToPrometheusMetricsConfig.cs
│ ├── ApplicationInsightsToPrometheusMetricsInitializer.cs
│ ├── InternalsVisibleTo.cs
│ ├── PrometheusMetrics.cs
│ └── StartupExtensions.cs
├── Allegro.Extensions.ApplicationInsights.sln
├── Allegro.Extensions.ApplicationInsights.sln.DotSettings
├── CHANGELOG.md
├── README.md
└── version.xml
├── Allegro.Extensions.AspNetCore
├── Allegro.Extensions.AspNetCore.Demo
│ ├── Allegro.Extensions.AspNetCore.Demo.csproj
│ ├── Controllers
│ │ ├── ErrorHandlingController.cs
│ │ ├── SkipOnProdController.cs
│ │ └── TestController.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ └── Startup.cs
├── Allegro.Extensions.AspNetCore.Tests.Unit
│ ├── Allegro.Extensions.AspNetCore.Tests.Unit.csproj
│ ├── ErrorHandling
│ │ ├── ErrorHandlingMiddlewareTests.cs
│ │ └── InvalidModelStateResponseFactoryTests.cs
│ └── SkipControllerFeatureProviderTests.cs
├── Allegro.Extensions.AspNetCore.sln
├── Allegro.Extensions.AspNetCore
│ ├── Allegro.Extensions.AspNetCore.csproj
│ ├── Attributes
│ │ └── SkipOnProdAttribute.cs
│ ├── ErrorHandling
│ │ ├── ErrorHandlingConfigurationBuilder.cs
│ │ ├── ErrorHandlingMiddlewareExtensions.cs
│ │ ├── IErrorSerializer.cs
│ │ ├── Internals
│ │ │ ├── ErrorHandlingMiddleware.cs
│ │ │ ├── ErrorResponse.cs
│ │ │ ├── InvalidModelStateResponseFactory.cs
│ │ │ └── SystemTextJsonWebErrorSerializer.cs
│ │ └── Models.cs
│ ├── Extensions
│ │ └── MvcBuilderExtensions.cs
│ ├── Features
│ │ └── SkipControllerFeatureProvider.cs
│ └── InternalsVisibleTo.cs
├── CHANGELOG.md
├── README.md
└── version.xml
├── Allegro.Extensions.Cqrs
├── Allegro.Extensions.Cqrs.Abstractions
│ ├── Allegro.Extensions.Cqrs.Abstractions.csproj
│ ├── Commands
│ │ ├── Command.cs
│ │ ├── ICommandDispatcher.cs
│ │ ├── ICommandHandler.cs
│ │ └── ICommandValidator.cs
│ ├── DecoratorAttribute.cs
│ └── Queries
│ │ ├── IQueryDispatcher.cs
│ │ ├── IQueryHandler.cs
│ │ ├── IQueryValidator.cs
│ │ └── Query.cs
├── Allegro.Extensions.Cqrs.Demo
│ ├── Allegro.Extensions.Cqrs.Demo.csproj
│ ├── Commands
│ │ └── BarCommand.cs
│ ├── Controllers
│ │ ├── CommandController.cs
│ │ └── QueryController.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Queries
│ │ └── BarQuery.cs
│ └── Startup.cs
├── Allegro.Extensions.Cqrs.FluentValidations
│ ├── Allegro.Extensions.Cqrs.FluentValidations.csproj
│ ├── FluentCommandValidator.cs
│ ├── FluentQueryValidator.cs
│ └── StartupExtensions.cs
├── Allegro.Extensions.Cqrs.Tests.Unit
│ ├── Allegro.Extensions.Cqrs.Tests.Unit.csproj
│ ├── CommandsSpec.cs
│ └── QueriesSpec.cs
├── Allegro.Extensions.Cqrs.sln
├── Allegro.Extensions.Cqrs
│ ├── Allegro.Extensions.Cqrs.csproj
│ ├── Commands
│ │ ├── CommandDispatcher.cs
│ │ └── StartupExtensions.cs
│ ├── InternalsVisibleTo.cs
│ └── Queries
│ │ ├── QueryDispatcher.cs
│ │ └── StartupExtensions.cs
├── CHANGELOG.md
├── README.md
└── version.xml
├── Allegro.Extensions.Dapper
├── Allegro.Extensions.Dapper.Postgres.Tests.Integration
│ ├── Allegro.Extensions.Dapper.Postgres.Tests.Integration.csproj
│ ├── DapperPostgresBinaryCopyClient.cs
│ ├── Helpers
│ │ ├── CustomWebApplicationFactory.cs
│ │ ├── FakeStartup.cs
│ │ └── SqlQueries.cs
│ ├── Models
│ │ └── TestModel.cs
│ ├── PostgresDapperClient.cs
│ └── appsettings.Test.json
├── Allegro.Extensions.Dapper.Postgres
│ ├── Abstractions
│ │ ├── DbType.cs
│ │ └── IDapperPostgresBinaryCopyClient.cs
│ ├── Allegro.Extensions.Dapper.Postgres.csproj
│ ├── DapperPostgresBinaryCopyClient.cs
│ ├── Exceptions
│ │ └── InvalidDbConnectionTypeException.cs
│ ├── Extensions
│ │ └── ServiceCollectionExtensions.cs
│ └── Factories
│ │ └── PostgresDatabaseConnectionFactory.cs
├── Allegro.Extensions.Dapper.sln
├── Allegro.Extensions.Dapper
│ ├── Abstractions
│ │ ├── IDapperClient.cs
│ │ └── IDatabaseConnectionFactory.cs
│ ├── Allegro.Extensions.Dapper.csproj
│ ├── Configurations
│ │ └── DatabaseConfiguration.cs
│ ├── DapperClient.cs
│ └── Extensions
│ │ └── ServiceCollectionExtensions.cs
├── CHANGELOG.md
├── README.md
└── version.xml
├── Allegro.Extensions.DependencyCall
├── Allegro.Extensions.DependencyCall.Abstractions
│ ├── Allegro.Extensions.DependencyCall.Abstractions.csproj
│ ├── IDependencyCallDispatcher.cs
│ ├── IDependencyCallMetrics.cs
│ └── IRequest.cs
├── Allegro.Extensions.DependencyCall.Metrics.Prometheus
│ ├── Allegro.Extensions.DependencyCall.Metrics.Prometheus.csproj
│ ├── DependencyCallBuilderExtensions.cs
│ └── PrometheusDependencyCallMetrics.cs
├── Allegro.Extensions.DependencyCall.Tests.Unit
│ ├── Allegro.Extensions.DependencyCall.Tests.Unit.csproj
│ ├── DependencyCallDispatcherSpec.cs
│ └── Fixture.cs
├── Allegro.Extensions.DependencyCall.sln
├── Allegro.Extensions.DependencyCall
│ ├── Allegro.Extensions.DependencyCall.csproj
│ ├── DependencyCall.cs
│ ├── DependencyCallDispatcher.cs
│ ├── NoOperationDependencyCallMetrics.cs
│ └── StartupExtensions.cs
├── CHANGELOG.md
├── README.md
└── version.xml
├── Allegro.Extensions.Financials
├── Allegro.Extensions.Financials.Tests.Unit
│ ├── Allegro.Extensions.Financials.Tests.Unit.csproj
│ ├── Extensions
│ │ └── MoneyExtensionsTests.cs
│ └── ValueObjects
│ │ └── MoneyTests.cs
├── Allegro.Extensions.Financials.sln
├── Allegro.Extensions.Financials
│ ├── Allegro.Extensions.Financials.csproj
│ ├── Extensions
│ │ └── MoneyExtensions.cs
│ └── ValueObjects
│ │ ├── Currency.cs
│ │ ├── Money.Operators.cs
│ │ └── Money.cs
├── CHANGELOG.md
├── README.md
└── version.xml
├── Allegro.Extensions.Globalization
├── Allegro.Extensions.Globalization.Tests
│ ├── Allegro.Extensions.Globalization.Tests.csproj
│ └── PolishPluralizerTests.cs
├── Allegro.Extensions.Globalization.sln
├── Allegro.Extensions.Globalization
│ ├── Allegro.Extensions.Globalization.csproj
│ └── Extensions
│ │ └── PolishPluralizer.cs
├── CHANGELOG.md
├── README.md
└── version.xml
├── Allegro.Extensions.Identifiers
├── Allegro.Extensions.Identifiers.Abstractions
│ ├── Allegro.Extensions.Identifiers.Abstractions.csproj
│ ├── IStronglyTypedEntity.cs
│ └── IStronglyTypedId.cs
├── Allegro.Extensions.Identifiers.AspNetCore
│ ├── Allegro.Extensions.Identifiers.AspNetCore.csproj
│ └── Swagger
│ │ └── StronglyTypedIdsSwaggerExtensions.cs
├── Allegro.Extensions.Identifiers.Demo
│ ├── Allegro.Extensions.Identifiers.Demo.csproj
│ ├── Controllers
│ │ └── TestController.cs
│ ├── Identifiers
│ │ ├── OrderId.cs
│ │ ├── PaymentId.cs
│ │ └── UserId.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ └── Startup.cs
├── Allegro.Extensions.Identifiers.sln
├── CHANGELOG.md
├── README.md
└── version.xml
├── Allegro.Extensions.NullableReferenceTypes
├── Allegro.Extensions.NullableReferenceTypes.Tests.Unit
│ ├── Allegro.Extensions.NullableReferenceTypes.Tests.Unit.csproj
│ └── Validators
│ │ └── ObjectValidatorTests.cs
├── Allegro.Extensions.NullableReferenceTypes.sln
├── Allegro.Extensions.NullableReferenceTypes
│ ├── Allegro.Extensions.NullableReferenceTypes.csproj
│ └── Validators
│ │ └── ObjectValidator.cs
├── CHANGELOG.md
├── README.md
└── version.xml
├── Allegro.Extensions.RateLimiting
├── Allegro.Extensions.RateLimiting.Tests.Unit
│ ├── Allegro.Extensions.RateLimiting.Tests.Unit.csproj
│ └── RateLimiterTests.cs
├── Allegro.Extensions.RateLimiting.sln
├── Allegro.Extensions.RateLimiting
│ ├── Allegro.Extensions.RateLimiting.csproj
│ ├── Events
│ │ ├── AvgRateCalculated.cs
│ │ ├── MaxRateChanged.cs
│ │ └── MaxRateExceeded.cs
│ ├── IRateLimiter.cs
│ ├── IRateLimiterWithVariableRate.cs
│ └── RateLimiter.cs
├── CHANGELOG.md
├── README.md
└── version.xml
├── Allegro.Extensions.Serialization
├── Allegro.Extensions.Serialization.Tests.Unit
│ ├── Allegro.Extensions.Serialization.Tests.Unit.csproj
│ └── EnumHelperTests.cs
├── Allegro.Extensions.Serialization.sln
├── Allegro.Extensions.Serialization
│ ├── Allegro.Extensions.Serialization.csproj
│ └── Extensions
│ │ └── EnumHelper.cs
├── CHANGELOG.md
├── README.md
└── version.xml
├── Allegro.Extensions.Validators
├── Allegro.Extensions.Validators.Tests.Unit
│ ├── Allegro.Extensions.Validators.Tests.Unit.csproj
│ └── InputValidatorTests.cs
├── Allegro.Extensions.Validators.sln
├── Allegro.Extensions.Validators
│ ├── Allegro.Extensions.Validators.csproj
│ ├── FluentValidationOptions.cs
│ ├── InputValidator.cs
│ ├── OptionsBuilderFluentValidationExtensions.cs
│ └── StartupExtensions.cs
├── CHANGELOG.md
├── README.md
└── version.xml
├── Directory.Build.props
├── Directory.Build.targets
└── Package.Build.props
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.sh text eol=lf
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.ApplicationInsights.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.ApplicationInsights
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.ApplicationInsights/**'
8 | - 'src/*'
9 | pull_request:
10 | branches: [ main ]
11 | paths:
12 | - 'src/Allegro.Extensions.ApplicationInsights/**'
13 | - 'src/*'
14 |
15 | jobs:
16 | ci1:
17 | uses: ./.github/workflows/template.yml
18 | with:
19 | projectName: Allegro.Extensions.ApplicationInsights.AspNetCore
20 | solutionName: Allegro.Extensions.ApplicationInsights
21 | ci2:
22 | uses: ./.github/workflows/template.yml
23 | with:
24 | projectName: Allegro.Extensions.ApplicationInsights.Prometheus
25 | solutionName: Allegro.Extensions.ApplicationInsights
26 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.ApplicationInsights.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.ApplicationInsights
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.ApplicationInsights_*'
7 |
8 | jobs:
9 | publish1:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.ApplicationInsights.AspNetCore
13 | solutionName: Allegro.Extensions.ApplicationInsights
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 | publish2:
24 | uses: ./.github/workflows/template.yml
25 | with:
26 | projectName: Allegro.Extensions.ApplicationInsights.Prometheus
27 | solutionName: Allegro.Extensions.ApplicationInsights
28 | publish: true
29 | tagName: ${{ github.ref_name }}
30 | secrets:
31 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
32 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
33 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
34 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
35 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
36 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
37 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.AspNetCore.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.AspNetCore
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.AspNetCore/**'
8 | - 'src/*'
9 | pull_request:
10 | branches: [ main ]
11 | paths:
12 | - 'src/Allegro.Extensions.AspNetCore/**'
13 | - 'src/*'
14 |
15 | jobs:
16 | ci:
17 | uses: ./.github/workflows/template.yml
18 | with:
19 | projectName: Allegro.Extensions.AspNetCore
20 | solutionName: Allegro.Extensions.AspNetCore
21 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.AspNetCore.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.AspNetCore
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.AspNetCore_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.AspNetCore
13 | solutionName: Allegro.Extensions.AspNetCore
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Cqrs.Abstractions.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.Cqrs.Abstractions
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.Cqrs/*'
8 | - 'src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/**'
9 | - 'src/*'
10 | pull_request:
11 | branches: [ main ]
12 | paths:
13 | - 'src/Allegro.Extensions.Cqrs/*'
14 | - 'src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/**'
15 | - 'src/*'
16 |
17 | jobs:
18 | ci:
19 | uses: ./.github/workflows/template.yml
20 | with:
21 | projectName: Allegro.Extensions.Cqrs.Abstractions
22 | solutionName: Allegro.Extensions.Cqrs
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Cqrs.Abstractions.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.Cqrs.Abstractions
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.Cqrs.Abstractions_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.Cqrs.Abstractions
13 | solutionName: Allegro.Extensions.Cqrs
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Cqrs.FluentValidations.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.Cqrs.FluentValidations
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.Cqrs/*'
8 | - 'src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.FluentValidations/**'
9 | - 'src/*'
10 | pull_request:
11 | branches: [ main ]
12 | paths:
13 | - 'src/Allegro.Extensions.Cqrs/*'
14 | - 'src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.FluentValidations/**'
15 | - 'src/*'
16 |
17 | jobs:
18 | ci:
19 | uses: ./.github/workflows/template.yml
20 | with:
21 | projectName: Allegro.Extensions.Cqrs.FluentValidations
22 | solutionName: Allegro.Extensions.Cqrs
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Cqrs.FluentValidations.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.Cqrs.FluentValidations
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.Cqrs.FluentValidations_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.Cqrs.FluentValidations
13 | solutionName: Allegro.Extensions.Cqrs
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Cqrs.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.Cqrs
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.Cqrs/*'
8 | - 'src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs/**'
9 | - 'src/*'
10 | pull_request:
11 | branches: [ main ]
12 | paths:
13 | - 'src/Allegro.Extensions.Cqrs/*'
14 | - 'src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs/**'
15 | - 'src/*'
16 |
17 | jobs:
18 | ci:
19 | uses: ./.github/workflows/template.yml
20 | with:
21 | projectName: Allegro.Extensions.Cqrs
22 | solutionName: Allegro.Extensions.Cqrs
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Cqrs.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.Cqrs
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.Cqrs_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.Cqrs
13 | solutionName: Allegro.Extensions.Cqrs
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Dapper.Postgres.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.Dapper.Postgres
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.Dapper/*'
8 | - 'src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres/**'
9 | - 'src/*'
10 | pull_request:
11 | branches: [ main ]
12 | paths:
13 | - 'src/Allegro.Extensions.Dapper/*'
14 | - 'src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres/**'
15 | - 'src/*'
16 |
17 | jobs:
18 | ci:
19 | uses: ./.github/workflows/template.yml
20 | with:
21 | projectName: Allegro.Extensions.Dapper.Postgres
22 | solutionName: Allegro.Extensions.Dapper
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Dapper.Postgres.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.Dapper.Postgres
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.Dapper.Postgres_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.Dapper.Postgres
13 | solutionName: Allegro.Extensions.Dapper
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Dapper.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.Dapper
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.Dapper/*'
8 | - 'src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper/**'
9 | - 'src/*'
10 | pull_request:
11 | branches: [ main ]
12 | paths:
13 | - 'src/Allegro.Extensions.Dapper/*'
14 | - 'src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper/**'
15 | - 'src/*'
16 |
17 | jobs:
18 | ci:
19 | uses: ./.github/workflows/template.yml
20 | with:
21 | projectName: Allegro.Extensions.Dapper
22 | solutionName: Allegro.Extensions.Dapper
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Dapper.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.Dapper
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.Dapper_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.Dapper
13 | solutionName: Allegro.Extensions.Dapper
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.DependencyCall.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.DependencyCall
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.DependencyCall/**'
8 | - 'src/*'
9 | pull_request:
10 | branches: [ main ]
11 | paths:
12 | - 'src/Allegro.Extensions.DependencyCall/**'
13 | - 'src/*'
14 |
15 | jobs:
16 | ci:
17 | uses: ./.github/workflows/template.yml
18 | with:
19 | projectName: Allegro.Extensions.DependencyCall
20 | solutionName: Allegro.Extensions.DependencyCall
21 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.DependencyCall.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.DependencyCall
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.DependencyCall_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.DependencyCall
13 | solutionName: Allegro.Extensions.DependencyCall
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Financials.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.Financials
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.Financials/**'
8 | - 'src/*'
9 | pull_request:
10 | branches: [ main ]
11 | paths:
12 | - 'src/Allegro.Extensions.Financials/**'
13 | - 'src/*'
14 |
15 | jobs:
16 | ci:
17 | uses: ./.github/workflows/template.yml
18 | with:
19 | projectName: Allegro.Extensions.Financials
20 | solutionName: Allegro.Extensions.Financials
21 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Financials.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.Financials
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.Financials_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.Financials
13 | solutionName: Allegro.Extensions.Financials
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Globalization.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.Globalization
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.Globalization/**'
8 | - 'src/*'
9 | pull_request:
10 | branches: [ main ]
11 | paths:
12 | - 'src/Allegro.Extensions.Globalization/**'
13 | - 'src/*'
14 |
15 | jobs:
16 | ci:
17 | uses: ./.github/workflows/template.yml
18 | with:
19 | projectName: Allegro.Extensions.Globalization
20 | solutionName: Allegro.Extensions.Globalization
21 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Globalization.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.Globalization
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.Globalization_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.Globalization
13 | solutionName: Allegro.Extensions.Globalization
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Identifiers.Abstractions.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.Identifiers.Abstractions
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.Identifiers/*'
8 | - 'src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Abstractions/**'
9 | - 'src/*'
10 | pull_request:
11 | branches: [ main ]
12 | paths:
13 | - 'src/Allegro.Extensions.Identifiers/*'
14 | - 'src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Abstractions/**'
15 | - 'src/*'
16 |
17 | jobs:
18 | ci:
19 | uses: ./.github/workflows/template.yml
20 | with:
21 | projectName: Allegro.Extensions.Identifiers.Abstractions
22 | solutionName: Allegro.Extensions.Identifiers
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Identifiers.Abstractions.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.Identifiers.Abstractions
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.Identifiers.Abstractions_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.Identifiers.Abstractions
13 | solutionName: Allegro.Extensions.Identifiers
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Identifiers.AspNetCore.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.Identifiers.AspNetCore
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.Identifiers/*'
8 | - 'src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.AspNetCore/**'
9 | - 'src/*'
10 | pull_request:
11 | branches: [ main ]
12 | paths:
13 | - 'src/Allegro.Extensions.Identifiers/*'
14 | - 'src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.AspNetCore/**'
15 | - 'src/*'
16 |
17 | jobs:
18 | ci:
19 | uses: ./.github/workflows/template.yml
20 | with:
21 | projectName: Allegro.Extensions.Identifiers.AspNetCore
22 | solutionName: Allegro.Extensions.Identifiers
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Identifiers.AspNetCore.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.Identifiers.AspNetCore
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.Identifiers.AspNetCore_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.Identifiers.AspNetCore
13 | solutionName: Allegro.Extensions.Identifiers
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.NullableReferenceTypes.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.NullableReferenceTypes
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.NullableReferenceTypes/**'
8 | - 'src/*'
9 | pull_request:
10 | branches: [ main ]
11 | paths:
12 | - 'src/Allegro.Extensions.NullableReferenceTypes/**'
13 | - 'src/*'
14 |
15 | jobs:
16 | ci:
17 | uses: ./.github/workflows/template.yml
18 | with:
19 | projectName: Allegro.Extensions.NullableReferenceTypes
20 | solutionName: Allegro.Extensions.NullableReferenceTypes
21 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.NullableReferenceTypes.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.NullableReferenceTypes
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.NullableReferenceTypes_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.NullableReferenceTypes
13 | solutionName: Allegro.Extensions.NullableReferenceTypes
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.RateLimiting.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.RateLimiting
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.RateLimiting/**'
8 | - 'src/*'
9 | pull_request:
10 | branches: [ main ]
11 | paths:
12 | - 'src/Allegro.Extensions.RateLimiting/**'
13 | - 'src/*'
14 |
15 | jobs:
16 | ci:
17 | uses: ./.github/workflows/template.yml
18 | with:
19 | projectName: Allegro.Extensions.RateLimiting
20 | solutionName: Allegro.Extensions.RateLimiting
21 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.RateLimiting.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.RateLimiting
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.RateLimiting_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.RateLimiting
13 | solutionName: Allegro.Extensions.RateLimiting
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Serialization.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.Serialization
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.Serialization/**'
8 | - 'src/*'
9 | pull_request:
10 | branches: [ main ]
11 | paths:
12 | - 'src/Allegro.Extensions.Serialization/**'
13 | - 'src/*'
14 |
15 | jobs:
16 | ci:
17 | uses: ./.github/workflows/template.yml
18 | with:
19 | projectName: Allegro.Extensions.Serialization
20 | solutionName: Allegro.Extensions.Serialization
21 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Serialization.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.Serialization
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.Serialization_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.Serialization
13 | solutionName: Allegro.Extensions.Serialization
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Validators.ci.yml:
--------------------------------------------------------------------------------
1 | name: Build Allegro.Extensions.Validators
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'src/Allegro.Extensions.Validators/**'
8 | - 'src/*'
9 | pull_request:
10 | branches: [ main ]
11 | paths:
12 | - 'src/Allegro.Extensions.Validators/**'
13 | - 'src/*'
14 |
15 | jobs:
16 | ci:
17 | uses: ./.github/workflows/template.yml
18 | with:
19 | projectName: Allegro.Extensions.Validators
20 | solutionName: Allegro.Extensions.Validators
21 |
--------------------------------------------------------------------------------
/.github/workflows/Allegro.Extensions.Validators.publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Allegro.Extensions.Validators
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'Allegro.Extensions.Validators_*'
7 |
8 | jobs:
9 | publish:
10 | uses: ./.github/workflows/template.yml
11 | with:
12 | projectName: Allegro.Extensions.Validators
13 | solutionName: Allegro.Extensions.Validators
14 | publish: true
15 | tagName: ${{ github.ref_name }}
16 | secrets:
17 | SM_CLIENT_CERT_PASSWORD: ${{ secrets.DIGICERT_SM_CLIENT_CERT_PASSWORD }}
18 | SM_CLIENT_CERT_FILE_B64: ${{ secrets.DIGICERT_SM_CLIENT_CERT_FILE_B64 }}
19 | SM_HOST: ${{ secrets.DIGICERT_SM_HOST }}
20 | SM_API_KEY: ${{ secrets.DIGICERT_SM_API_KEY }}
21 | SM_CODE_SIGNING_CERT_SHA1_HASH: ${{ secrets.DIGICERT_SM_CODE_SIGNING_CERT_SHA1_HASH }}
22 | nugetApiKey: ${{ secrets.NUGET_API_KEY }}
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .fake/
2 | .idea/
3 | .ionide/
4 | .paket/
5 | .vscode/
6 | App_Data/
7 | packages/
8 | obj/
9 | bin/
10 | build/
11 | deploy/
12 | TestResults/
13 | *.bak
14 | *.user
15 | *.suo
16 | *.ncrunchsolution
17 | *.ncrunchproject
18 | *.nupkg
19 | *.snupkg
20 | .vs/
21 | **/frontend/node_modules/
22 | **/frontend/coverage/
23 | DeploymentScripts/temp/
24 | BenchmarkDotNet.Artifacts
25 | paket-files/
26 | .DS_Store
27 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | ## Pull requests
4 |
5 | * for small changes, no need to add separate issue, defining problem in pull request is enough
6 | * if issue exists, reference it from PR title or description using GitHub magic words like *resolves #issue-number*
7 | * before making significant changes, please contact us via issues to discuss your plans and decrease number of changes after Pull Request is created
8 | * create pull requests to **main** branch
9 | * when updating a package, make sure to:
10 | * update its README.md
11 | * update its CHANGELOG.md
12 | * update its version
13 | * consider presenting usage in Demo app (`/samples`)
14 | * add tests
15 | * when creating a new package, make sure to:
16 | * maintain the repo structure (see existing packages)
17 | * add code analyzers
18 | * create the package's README.md
19 | * initialize the package's CHANGELOG.md
20 | * add tests
21 | * consider presenting usage in Demo app (`/samples`)
22 | * reference the package from README.md in repo's root
23 |
24 | ## Coding style
25 |
26 | The coding style is guarded by the analyzers (such as stylecop) and .editorconfig.
27 | Make sure to follow the defined standards.
--------------------------------------------------------------------------------
/ap-catalog-info.yaml:
--------------------------------------------------------------------------------
1 | # https://backstage.io/docs/features/software-catalog/descriptor-format#kind-component
2 | apiVersion: backstage.io/v1alpha1
3 | kind: Component
4 | metadata:
5 | name: AllegroExtensions
6 | description: "This repo contains utility packages that can be shared between Allegro services, but are not required. "
7 | title: Allegro Extensions
8 | annotations:
9 | backstage.io/techdocs-ref: dir:.
10 | allegropay/entity-updated-at: '2023-11-03T08:15'
11 | github.com/project-slug: allegro/dotnet-utils
12 | links: []
13 | spec:
14 | type: library
15 | owner: aard
16 | lifecycle: production
17 | system: application-platform
18 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | {%
2 | include-markdown "../README.md"
3 | start=""
4 | end=""
5 | rewrite-relative-urls=true
6 | %}
7 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "8.0.100",
4 | "rollForward": "latestFeature"
5 | },
6 | "msbuild-sdks": {
7 | "Allegro.DotnetSdk": "2.1.0"
8 | }
9 | }
--------------------------------------------------------------------------------
/mkdocs.yml:
--------------------------------------------------------------------------------
1 | site_name: Allegro Pay Backstage docs
2 |
3 | plugins:
4 | - techdocs-core
5 | - include-markdown
6 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore.UnitTests/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{cs,fs}]
2 | dotnet_diagnostic.CS1591.severity = none
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore.UnitTests/Allegro.Extensions.ApplicationInsights.AspNetCore.UnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | runtime; build; native; contentfiles; analyzers; buildtransitive
16 | all
17 |
18 |
19 | runtime; build; native; contentfiles; analyzers; buildtransitive
20 | all
21 |
22 |
23 | all
24 | runtime; build; native; contentfiles; analyzers
25 |
26 |
27 | all
28 | runtime; compile; build; native; contentfiles; analyzers
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore.UnitTests/FilterTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.ApplicationInsights.DataContracts;
2 | using Microsoft.Extensions.Logging.Abstractions;
3 |
4 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
5 |
6 | public class FilterTests
7 | where TDependencyForFilter : DependencyForFilter
8 | where TRequestForFilter : RequestForFilter
9 | {
10 | public void ApplyDependencyRules(
11 | DependencyTelemetry dependencyTelemetry,
12 | string filter,
13 | Func dependencyMap)
14 | {
15 | var predicates =
16 | ExcludeFromSamplingTelemetryInitializer
17 | .CreatePredicates(
18 | NullLogger.Instance,
19 | new Dictionary() { { "any", filter } });
20 |
21 | ExcludeFromSamplingTelemetryInitializer.ApplyDependencyRules(
22 | dependencyTelemetry,
23 | predicates,
24 | dependencyMap);
25 | }
26 |
27 | public void ApplyRequestRules(
28 | RequestTelemetry requestTelemetry, string filter, Func requestMap)
29 | {
30 | var predicates =
31 | ExcludeFromSamplingTelemetryInitializer
32 | .CreatePredicates(
33 | NullLogger.Instance,
34 | new Dictionary() { { "any", filter } });
35 |
36 | ExcludeFromSamplingTelemetryInitializer.ApplyRequestRules(
37 | requestTelemetry,
38 | predicates,
39 | requestMap);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/Allegro.Extensions.ApplicationInsights.AspNetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | true
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | all
22 | runtime; build; native; contentfiles; analyzers
23 |
24 |
25 | all
26 | runtime; compile; build; native; contentfiles; analyzers
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/CloudApplicationInfo/TelemetryCloudApplicationInfo.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
2 |
3 | ///
4 | /// Information about cloud environment of the app
5 | ///
6 | public class TelemetryCloudApplicationInfo : Dictionary
7 | {
8 | ///
9 | /// Default value when no value provided
10 | ///
11 | public const string EmptyPlaceholder = "empty";
12 |
13 | ///
14 | /// ApplicationName Key
15 | ///
16 | public const string ApplicationNameKey = "ApplicationName";
17 |
18 | ///
19 | /// Application name (i.e. name of the k8s service)
20 | ///
21 | public string? ApplicationName
22 | {
23 | get => this.GetValueOrDefault(nameof(ApplicationName));
24 | set
25 | {
26 | if (value != null)
27 | this[nameof(ApplicationName)] = value;
28 | }
29 | }
30 |
31 | ///
32 | /// Load cloud application info from environment variables
33 | ///
34 | public virtual void LoadFromEnv()
35 | {
36 | var applicationName =
37 | Environment.GetEnvironmentVariable(ApplicationNameKey)
38 | ?? EmptyPlaceholder;
39 |
40 | Add(ApplicationNameKey, applicationName);
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/CloudApplicationInfo/TelemetryCloudApplicationInfoTelemetryInitializer.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.ApplicationInsights.Channel;
2 | using Microsoft.ApplicationInsights.DataContracts;
3 | using Microsoft.ApplicationInsights.Extensibility;
4 | using Microsoft.Extensions.Options;
5 |
6 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
7 |
8 | internal class TelemetryCloudApplicationInfoTelemetryInitializer : ITelemetryInitializer
9 | {
10 | private readonly IOptions _cloudApplicationInfo;
11 |
12 | public TelemetryCloudApplicationInfoTelemetryInitializer(IOptions cloudApplicationInfo)
13 | {
14 | _cloudApplicationInfo = cloudApplicationInfo;
15 | }
16 |
17 | public void Initialize(ITelemetry telemetry)
18 | {
19 | telemetry.Context.Cloud.RoleName = _cloudApplicationInfo.Value.ApplicationName;
20 |
21 | foreach (var metadata in _cloudApplicationInfo.Value)
22 | {
23 | if (metadata.Key != TelemetryCloudApplicationInfo.ApplicationNameKey)
24 | {
25 | SetTelemetryProperty(telemetry, metadata.Key, metadata.Value);
26 | }
27 | }
28 | }
29 |
30 | private static void SetTelemetryProperty(ITelemetry telemetry, string key, string value)
31 | {
32 | if (telemetry is ISupportProperties propTelemetry &&
33 | !string.IsNullOrEmpty(value) &&
34 | !propTelemetry.Properties.ContainsKey(key))
35 | {
36 | propTelemetry.Properties.Add(key, value);
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/FlushAppInsightsHostedService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.ApplicationInsights;
2 | using Microsoft.Extensions.Hosting;
3 |
4 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
5 |
6 | internal class FlushAppInsightsHostedService : IHostedService
7 | {
8 | private readonly TelemetryClient _telemetryClient;
9 | private readonly IHostApplicationLifetime _hostLifetime;
10 |
11 | public FlushAppInsightsHostedService(TelemetryClient telemetryClient, IHostApplicationLifetime hostLifetime)
12 | {
13 | _telemetryClient = telemetryClient;
14 | _hostLifetime = hostLifetime;
15 | }
16 |
17 | public Task StartAsync(CancellationToken cancellationToken)
18 | {
19 | // flushes right after graceful shutdown of hosted services finished
20 | _hostLifetime.ApplicationStopped.Register(() => _telemetryClient.Flush());
21 |
22 | return Task.CompletedTask;
23 | }
24 |
25 | public Task StopAsync(CancellationToken cancellationToken)
26 | {
27 | // flushes right after graceful shutdown of hosted services started
28 | _telemetryClient.Flush();
29 |
30 | return Task.CompletedTask;
31 | }
32 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/InternalsVisibleTo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo(
4 | "Allegro.Extensions.ApplicationInsights.AspNetCore.UnitTests")]
5 | [assembly: InternalsVisibleTo(
6 | "Allegro.Extensions.ApplicationInsights.Demo.UnitTests")]
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/SamplingConfig/PrintSamplingConfigurationService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Hosting;
2 | using Microsoft.Extensions.Logging;
3 | using Microsoft.Extensions.Options;
4 |
5 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
6 |
7 | internal class PrintSamplingConfigurationService : IHostedService
8 | {
9 | private readonly SamplingConfig _samplingConfig;
10 | private readonly ILogger _logger;
11 |
12 | public PrintSamplingConfigurationService(
13 | IOptions samplingConfig,
14 | ILogger logger)
15 | {
16 | _samplingConfig = samplingConfig.Value;
17 | _logger = logger;
18 | }
19 |
20 | public Task StartAsync(CancellationToken cancellationToken)
21 | {
22 | #pragma warning disable CA1848
23 | _logger.LogInformation("SamplingConfig: {@config}", _samplingConfig);
24 | #pragma warning restore CA1848
25 | return Task.CompletedTask;
26 | }
27 |
28 | public Task StopAsync(CancellationToken cancellationToken)
29 | {
30 | return Task.CompletedTask;
31 | }
32 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/SamplingConfig/SamplingConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
2 |
3 | ///
4 | /// Configuration for sampling
5 | ///
6 | public record SamplingConfig
7 | {
8 | ///
9 | /// Allow to set sampling mode
10 | ///
11 | public SamplingMode SamplingMode { get; init; }
12 |
13 | ///
14 | /// Sampling percentage for fixed mode
15 | ///
16 | public double? FixedSamplingPercentage { get; init; }
17 |
18 | ///
19 | /// A semi-colon delimited list of types that you don't want to be subject to sampling.
20 | /// Recognized types are: Dependency, Event, Exception, PageView, Request, Trace. All telemetry of the specified types is transmitted; the types that aren't specified will be sampled.
21 | ///
22 | public string SamplingExcludedTypes { get; init; } = "Event;Exception;Trace;PageView";
23 |
24 | ///
25 | /// Advanced configuration for adaptive sampling
26 | ///
27 | public AdaptiveSamplingConfig AdaptiveSamplingConfig { get; init; } = new AdaptiveSamplingConfig();
28 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/SamplingConfig/SamplingMode.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
2 |
3 | ///
4 | /// Sampling modes
5 | /// AdaptiveWithRules or FixedWithRules enable sampling ODATA exclusions rules
6 | ///
7 | public enum SamplingMode
8 | {
9 | ///
10 | /// Adaptive sampling with enabled ODATA exclusion rules
11 | ///
12 | AdaptiveWithRules,
13 |
14 | ///
15 | /// Adaptive sampling without rules
16 | ///
17 | Adaptive,
18 |
19 | ///
20 | /// Fixed sampling with enabled ODATA exclusion rules
21 | ///
22 | FixedWithRules,
23 |
24 | ///
25 | /// Fixed sampling without rules
26 | ///
27 | Fixed,
28 |
29 | ///
30 | /// No sampling at all
31 | ///
32 | Disabled
33 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/SamplingExclusions/DependencyForFilter.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.ApplicationInsights.DataContracts;
2 |
3 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
4 |
5 | ///
6 | /// Default dependency filter types for ODATA exclusion rules
7 | ///
8 | [Serializable]
9 | public record DependencyForFilter
10 | {
11 | ///
12 | /// CloudRoleName of dependency
13 | ///
14 | public string CloudRoleName { get; }
15 |
16 | ///
17 | /// Type of dependency
18 | ///
19 | public string Type { get; }
20 |
21 | ///
22 | /// Target of dependency
23 | ///
24 | public string Target { get; }
25 |
26 | ///
27 | /// Name of dependency
28 | ///
29 | public string Name { get; }
30 |
31 | ///
32 | /// Duration of dependency
33 | ///
34 | public double Duration { get; }
35 |
36 | ///
37 | /// Success of dependency
38 | ///
39 | public bool? Success { get; }
40 |
41 | ///
42 | /// ResultCode of dependency
43 | ///
44 | public string ResultCode { get; }
45 |
46 | ///
47 | /// Maps dependencyTelemetry to filter understand by ODATA engine
48 | ///
49 | ///
50 | public DependencyForFilter(DependencyTelemetry dependencyTelemetry)
51 | {
52 | Type = dependencyTelemetry.Type ?? string.Empty;
53 | Target = dependencyTelemetry.Target ?? string.Empty;
54 | Name = dependencyTelemetry.Name ?? string.Empty;
55 | Duration = dependencyTelemetry.Duration.TotalMilliseconds;
56 | Success = dependencyTelemetry.Success;
57 | CloudRoleName = dependencyTelemetry.Context?.Cloud?.RoleName ?? string.Empty;
58 | ResultCode = dependencyTelemetry.ResultCode ?? string.Empty;
59 | }
60 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/SamplingExclusions/ExcludeFromSamplingTelemetryConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
2 |
3 | ///
4 | /// Configuration for sampling exclusion ODATA rules
5 | ///
6 | public record ExcludeFromSamplingTelemetryConfig
7 | {
8 | ///
9 | /// Sampling dependency exclusion ODATA rules
10 | ///
11 | public Dictionary? DependencyRules { get; init; }
12 |
13 | ///
14 | /// Sampling request exclusion ODATA rules
15 | ///
16 | public Dictionary? RequestRules { get; init; }
17 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/SamplingExclusions/RequestForFilter.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.ApplicationInsights.DataContracts;
2 |
3 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
4 |
5 | ///
6 | /// Default request filter types for ODATA exclusion rules
7 | ///
8 | [Serializable]
9 | public record RequestForFilter
10 | {
11 | ///
12 | /// Maps requestTelemetry to filter understand by ODATA engine
13 | ///
14 | ///
15 | public RequestForFilter(RequestTelemetry requestTelemetry)
16 | {
17 | Name = requestTelemetry.Name ?? string.Empty;
18 | Duration = requestTelemetry.Duration.TotalMilliseconds;
19 | Success = requestTelemetry.Success;
20 | CloudRoleName = requestTelemetry.Context?.Cloud?.RoleName ?? string.Empty;
21 | ResponseCode = requestTelemetry.ResponseCode ?? string.Empty;
22 | Url = requestTelemetry.Url?.ToString() ?? string.Empty;
23 | }
24 |
25 | ///
26 | /// CloudRoleName of request
27 | ///
28 | public string CloudRoleName { get; }
29 |
30 | ///
31 | /// Name of request
32 | ///
33 | public string Name { get; }
34 |
35 | ///
36 | /// Duration of request
37 | ///
38 | public double Duration { get; }
39 |
40 | ///
41 | /// Success of request
42 | ///
43 | public bool? Success { get; }
44 |
45 | ///
46 | /// ResponseCode of request
47 | ///
48 | public string ResponseCode { get; }
49 |
50 | ///
51 | /// Url of request
52 | ///
53 | public string Url { get; }
54 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/SendConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
2 |
3 | ///
4 | /// Configuration for disabling/enabling sending telemetry from local machine
5 | ///
6 | public record SendConfig
7 | {
8 | ///
9 | /// Disable/enable sending telemetry from local machine
10 | ///
11 | public bool DisableLocally { get; init; } = true;
12 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/StartupLogger/StartupLogger.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Logging;
2 |
3 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
4 |
5 | ///
6 | /// Separate instance of logger for logging purposes in TelemetryInitializers
7 | ///
8 | public interface ITelemetryInitializerLogger : ILogger
9 | { }
10 |
11 | internal class TelemetryInitializerLogger : Logger, ITelemetryInitializerLogger
12 | {
13 | public TelemetryInitializerLogger(ILoggerFactory factory) : base(factory)
14 | {
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/TelemetryContext/TelemetryContext.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Concurrent;
2 |
3 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
4 |
5 | ///
6 | /// Scoped to async local telemetry context which provide additional medata for each telemetry within scope
7 | ///
8 | public class TelemetryContext : ConcurrentDictionary
9 | {
10 | internal static readonly AsyncLocal _context = new AsyncLocal();
11 |
12 | ///
13 | /// Scoped to async local telemetry context which provide additional medata for each telemetry within scope
14 | ///
15 | public static TelemetryContext Current
16 | {
17 | get => _context.Value ??= new TelemetryContext();
18 | private set => _context.Value = value;
19 | }
20 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/TelemetryContext/TelemetryContextInitializer.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.ApplicationInsights.Channel;
2 | using Microsoft.ApplicationInsights.DataContracts;
3 | using Microsoft.ApplicationInsights.Extensibility;
4 | using Microsoft.AspNetCore.Http;
5 |
6 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
7 |
8 | internal class TelemetryContextInitializer : ITelemetryInitializer
9 | {
10 | private readonly IHttpContextAccessor _contextAccessor;
11 |
12 | public TelemetryContextInitializer(IHttpContextAccessor contextAccessor)
13 | {
14 | _contextAccessor = contextAccessor;
15 | }
16 |
17 | public void Initialize(ITelemetry telemetry)
18 | {
19 | TelemetryContext context;
20 |
21 | if (TelemetryContext._context?.Value == null)
22 | {
23 | if (_contextAccessor.HttpContext?.Items != null && _contextAccessor.HttpContext.Items.ContainsKey(nameof(TelemetryContext)))
24 | {
25 | context = (TelemetryContext)_contextAccessor.HttpContext.Items[nameof(TelemetryContext)];
26 | }
27 | else
28 | {
29 | return;
30 | }
31 | }
32 | else
33 | {
34 | context = TelemetryContext.Current;
35 | }
36 |
37 | var propTelemetry = (ISupportProperties)telemetry;
38 |
39 | foreach (var keyValue in context)
40 | SetProperty(propTelemetry, keyValue.Key, keyValue.Value);
41 | }
42 |
43 | private static void SetProperty(ISupportProperties propTelemetry, string key, string value)
44 | {
45 | if (!string.IsNullOrEmpty(value) &&
46 | !propTelemetry.Properties.ContainsKey(key))
47 | propTelemetry.Properties.Add(key, value);
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.AspNetCore/TelemetryContext/TelemetryContextMiddleware.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.AspNetCore.Http;
4 |
5 | namespace Allegro.Extensions.ApplicationInsights.AspNetCore;
6 |
7 | internal class TelemetryContextMiddleware
8 | {
9 | private readonly RequestDelegate _next;
10 |
11 | public TelemetryContextMiddleware(RequestDelegate next)
12 | {
13 | _next = next;
14 | }
15 |
16 | public async Task InvokeAsync(HttpContext context)
17 | {
18 | var current = TelemetryContext.Current;
19 | context.Items.Add(nameof(TelemetryContext), current);
20 | await _next(context);
21 | }
22 | }
23 |
24 | internal static class TelemetryContextMiddlewareExtensions
25 | {
26 | public static IApplicationBuilder UseTelemetryContextMiddleware(this IApplicationBuilder builder)
27 | {
28 | return builder.UseMiddleware();
29 | }
30 | }
31 |
32 | internal class TelemetryContextMiddlewareStartupFilter : IStartupFilter
33 | {
34 | public Action Configure(Action next)
35 | {
36 | return app =>
37 | {
38 | app.UseTelemetryContextMiddleware();
39 | next(app);
40 | };
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo.UnitTests/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{cs,fs}]
2 | dotnet_diagnostic.CS1591.severity = none
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo.UnitTests/Allegro.Extensions.ApplicationInsights.Demo.UnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | runtime; build; native; contentfiles; analyzers; buildtransitive
16 | all
17 |
18 |
19 | runtime; build; native; contentfiles; analyzers; buildtransitive
20 | all
21 |
22 |
23 | all
24 | runtime; build; native; contentfiles; analyzers
25 |
26 |
27 | all
28 | runtime; compile; build; native; contentfiles; analyzers
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo.UnitTests/SamplingFilterTests.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.ApplicationInsights.AspNetCore;
2 | using AutoFixture;
3 | using FluentAssertions;
4 | using Microsoft.ApplicationInsights.DataContracts;
5 |
6 | namespace Allegro.Extensions.ApplicationInsights.Demo.UnitTests;
7 |
8 | public class SamplingFilterTests : FilterTests
9 | {
10 | [Theory]
11 | [InlineData("GET Method", "skyfall", "Team eq 'skyfall'", true)]
12 | [InlineData("GET Method", "skyfall", "OperationName eq 'GET Method'", true)]
13 | public void Dependencies_Rules(string operationName, string team, string filter, bool shouldExclude)
14 | {
15 | var fixture = new Fixture();
16 | var dependency = new DependencyTelemetry(
17 | fixture.Create(),
18 | fixture.Create(),
19 | fixture.Create(),
20 | null);
21 | dependency.Context.Operation.Name = operationName;
22 | dependency.Properties[nameof(CustomTelemetryCloudApplicationInfo.TeamName)] = team;
23 |
24 | CustomDependencyForFilter DependencyMap(DependencyTelemetry d) => new(d);
25 |
26 | ApplyDependencyRules(dependency, filter, DependencyMap);
27 |
28 | ((ISupportSampling)dependency).SamplingPercentage.Should().Be(shouldExclude ? 100 : null);
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo/Allegro.Extensions.ApplicationInsights.Demo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | all
15 | runtime; build; native; contentfiles; analyzers
16 |
17 |
18 | all
19 | runtime; compile; build; native; contentfiles; analyzers
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo/Controllers/WeatherForecastController.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Http;
2 | using Allegro.Extensions.ApplicationInsights.AspNetCore;
3 | using Microsoft.AspNetCore.Mvc;
4 | using Microsoft.Extensions.Logging;
5 |
6 | #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
7 |
8 | namespace Allegro.Extensions.ApplicationInsights.Demo.Controllers;
9 |
10 | public record WeatherForecast(DateTime Date, int TemperatureC, string Summary);
11 |
12 | [ApiController]
13 | [Route("[controller]")]
14 | public class WeatherForecastController : ControllerBase
15 | {
16 | private static readonly string[] Summaries = new[]
17 | {
18 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
19 | };
20 |
21 | private readonly ILogger _logger;
22 | private readonly IHttpClientFactory _httpClientFactory;
23 |
24 | public WeatherForecastController(ILogger logger, IHttpClientFactory httpClientFactory)
25 | {
26 | _logger = logger;
27 | _httpClientFactory = httpClientFactory;
28 | }
29 |
30 | [HttpGet(Name = "GetWeatherForecast")]
31 | public async Task> Get()
32 | {
33 | TelemetryContext.Current["TraceIdentifier"] = HttpContext.TraceIdentifier;
34 | var client = _httpClientFactory.CreateClient();
35 | await client.GetAsync("https://asd/asd/12331/3321");
36 | // return Task.FromResult>(
37 | // Enumerable.Range(1, 5).Select(
38 | // index => new WeatherForecast(
39 | // DateTime.Now.AddDays(index),
40 | // Random.Shared.Next(-20, 55),
41 | // Summaries[Random.Shared.Next(Summaries.Length)]))
42 | // .ToArray());
43 | return
44 | Enumerable.Range(1, 5).Select(
45 | index => new WeatherForecast(
46 | DateTime.Now.AddDays(index),
47 | Random.Shared.Next(-20, 55),
48 | Summaries[Random.Shared.Next(Summaries.Length)]))
49 | .ToArray();
50 | }
51 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo/CustomDependencyForFilter.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.ApplicationInsights.AspNetCore;
2 | using Microsoft.ApplicationInsights.DataContracts;
3 | #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
4 |
5 | namespace Allegro.Extensions.ApplicationInsights.Demo;
6 |
7 | public record CustomRequestForFilter : RequestForFilter
8 | {
9 | public string Team { get; }
10 |
11 | public CustomRequestForFilter(RequestTelemetry requestTelemetry) : base(requestTelemetry)
12 | {
13 | Team = requestTelemetry.Properties[nameof(CustomTelemetryCloudApplicationInfo.TeamName)];
14 | }
15 | }
16 |
17 | public record CustomDependencyForFilter : DependencyForFilter
18 | {
19 | public string OperationName { get; }
20 | public string Team { get; }
21 |
22 | public CustomDependencyForFilter(DependencyTelemetry dependencyTelemetry) : base(dependencyTelemetry)
23 | {
24 | OperationName = dependencyTelemetry.Context.Operation.Name;
25 | Team = dependencyTelemetry.Properties[nameof(CustomTelemetryCloudApplicationInfo.TeamName)];
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo/CustomTelemetryCloudApplicationInfo.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.ApplicationInsights.AspNetCore;
2 |
3 | namespace Allegro.Extensions.ApplicationInsights.Demo;
4 |
5 | internal class CustomTelemetryCloudApplicationInfo : TelemetryCloudApplicationInfo
6 | {
7 | ///
8 | /// Name of the team assigned to the service
9 | ///
10 | public string? TeamName
11 | {
12 | get => this.GetValueOrDefault(nameof(TeamName));
13 | set
14 | {
15 | if (value != null)
16 | {
17 | this[nameof(TeamName)] = value;
18 | }
19 | }
20 | }
21 |
22 | public override void LoadFromEnv()
23 | {
24 | base.LoadFromEnv();
25 | Add(nameof(TeamName), Environment.GetEnvironmentVariable(nameof(TeamName)) ?? EmptyPlaceholder);
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo/InternalsVisibleTo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo(
4 | "Allegro.Extensions.ApplicationInsights.Demo.UnitTests")]
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo/Program.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.ApplicationInsights.AspNetCore;
2 | using Allegro.Extensions.ApplicationInsights.Demo;
3 | using Allegro.Extensions.ApplicationInsights.Prometheus;
4 | using Microsoft.Extensions.Logging;
5 | using Prometheus;
6 |
7 | var builder = WebApplication.CreateBuilder(args);
8 |
9 | builder.Services.AddControllers();
10 | builder.Services.AddHttpClient();
11 | builder.Services.AddEndpointsApiExplorer();
12 | builder.Services.AddSwaggerGen();
13 | builder.Services.AddApplicationInsightsTelemetry();
14 | builder.Services.AddApplicationInsightsExtensions(builder.Configuration, builder.Environment, b =>
15 | {
16 | void ConfigureCloudInfo(CustomTelemetryCloudApplicationInfo p)
17 | {
18 | p.TeamName = "skyfall";
19 | p.ApplicationName = "demos-app-insights";
20 | }
21 |
22 | b.ConfigureTelemetryInitializerLogger(p => p.AddConsole());
23 | b.AddApplicationInsightsCloudApplicationInfo(ConfigureCloudInfo);
24 | b.AddApplicationInsightsSamplingConfig();
25 | b.AddApplicationInsightsTelemetryContext();
26 | b.AddApplicationInsightsFlush();
27 | b.AddApplicationInsightsSendConfig();
28 | b.AddApplicationInsightsSamplingExclusions(p => new CustomDependencyForFilter(p), p => new CustomRequestForFilter(p));
29 | }); // customization
30 | builder.Services.AddApplicationInsightsToPrometheus(builder.Configuration); // prometheus
31 |
32 | var app = builder.Build();
33 |
34 | if (app.Environment.IsDevelopment())
35 | {
36 | app.UseSwagger();
37 | app.UseSwaggerUI();
38 | }
39 |
40 | app.UseMetricServer();
41 | app.UseHttpsRedirection();
42 | app.UseAuthorization();
43 | app.MapControllers();
44 | app.Run();
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/launchsettings.json",
3 | "iisSettings": {
4 | "windowsAuthentication": false,
5 | "anonymousAuthentication": true,
6 | "iisExpress": {
7 | "applicationUrl": "http://localhost:2790",
8 | "sslPort": 44348
9 | }
10 | },
11 | "profiles": {
12 | "Allegro.Extensions.ApplicationInsights.Demo": {
13 | "commandName": "Project",
14 | "dotnetRunMessages": true,
15 | "launchBrowser": true,
16 | "launchUrl": "swagger",
17 | "applicationUrl": "https://localhost:7123;http://localhost:5202",
18 | "environmentVariables": {
19 | "ASPNETCORE_ENVIRONMENT": "Development"
20 | }
21 | },
22 | "IIS Express": {
23 | "commandName": "IISExpress",
24 | "launchBrowser": true,
25 | "launchUrl": "swagger",
26 | "environmentVariables": {
27 | "ASPNETCORE_ENVIRONMENT": "Development"
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Demo/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ApplicationInsights": {
3 | "DisableLocally": true,
4 | "SamplingMode": "AdaptiveWithRules",
5 | "FixedSamplingPercentage": 0.01,
6 | "ExcludeFromSamplingTelemetryConfig": {
7 | "DependencyRules": {
8 | "AzureServiceBus": "Type eq 'Azure Service Bus' and (duration ge 5000 or success eq false)"
9 | },
10 | "RequestRules": {
11 | "MyService": "Team eq 'skyfall'"
12 | }
13 | },
14 | "ApplicationInsightsToPrometheusMetrics": {
15 | "DependenciesTypesIncluded": [
16 | "HTTP"
17 | ],
18 | "IncludeBusRequests": false,
19 | "ShouldGeneralizeHttpDependencyOperationName": false,
20 | "ShouldGeneralizeHttpDependencyTargetUrl": false,
21 | "MaxUrisPerHost": 100
22 | },
23 | "ConnectionString": "InstrumentationKey=11955cd8-5cd1-4fde-803b-cb31b8b320e4;IngestionEndpoint=https://westeurope-3.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Prometheus.UnitTests/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{cs,fs}]
2 | dotnet_diagnostic.CS1591.severity = none
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Prometheus.UnitTests/Allegro.Extensions.ApplicationInsights.Prometheus.UnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | runtime; build; native; contentfiles; analyzers; buildtransitive
15 | all
16 |
17 |
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 | all
20 |
21 |
22 | all
23 | runtime; build; native; contentfiles; analyzers
24 |
25 |
26 | all
27 | runtime; compile; build; native; contentfiles; analyzers
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Prometheus/Allegro.Extensions.ApplicationInsights.Prometheus.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | true
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | all
15 | runtime; build; native; contentfiles; analyzers
16 |
17 |
18 | all
19 | runtime; compile; build; native; contentfiles; analyzers
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Prometheus/ApplicationInsightsToPrometheusMetricsConfig.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.ApplicationInsights.Prometheus;
2 |
3 | ///
4 | /// Configuration class for ApplicationInsightsToPrometheusMetrics mechanism
5 | ///
6 | public class ApplicationInsightsToPrometheusMetricsConfig
7 | {
8 | ///
9 | /// Section path for this configuration class
10 | ///
11 | public const string SectionName = "ApplicationInsights:ApplicationInsightsToPrometheusMetrics";
12 |
13 | ///
14 | /// Which dependency types should be exported
15 | ///
16 | public List DependenciesTypesIncluded { get; set; } = new();
17 |
18 | ///
19 | /// Should include Azure Bus requests
20 | ///
21 | public bool IncludeBusRequests { get; set; }
22 |
23 | ///
24 | /// Should generalize http dependency operation name
25 | ///
26 | public bool ShouldGeneralizeHttpDependencyOperationName { get; set; }
27 |
28 | ///
29 | /// Should generalize http dependency target url
30 | ///
31 | public bool ShouldGeneralizeHttpDependencyTargetUrl { get; set; }
32 |
33 | ///
34 | /// How many uris per host can be exported before circuit break
35 | ///
36 | public int MaxUrisPerHost { get; set; } = 100;
37 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Prometheus/InternalsVisibleTo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Allegro.Extensions.ApplicationInsights.Prometheus.UnitTests")]
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Prometheus/PrometheusMetrics.cs:
--------------------------------------------------------------------------------
1 | using Prometheus;
2 |
3 | namespace Allegro.Extensions.ApplicationInsights.Prometheus;
4 |
5 | internal class PrometheusMetrics
6 | {
7 | public Histogram ApplicationInsightsDependencyDuration { get; }
8 | public Histogram ApplicationInsightsRequestDuration { get; }
9 |
10 | public PrometheusMetrics(IMetricFactory? metrics = null)
11 | {
12 | metrics ??= Metrics.WithCustomRegistry(Metrics.DefaultRegistry);
13 | ApplicationInsightsDependencyDuration = DependencyHistogramFactory(metrics);
14 | ApplicationInsightsRequestDuration = RequestHistogramFactory(metrics);
15 | }
16 |
17 | private static Histogram DependencyHistogramFactory(IMetricFactory metrics)
18 | {
19 | return metrics.CreateHistogram(
20 | "ai_dependency_duration_seconds",
21 | "The duration of dependency call",
22 | new HistogramConfiguration
23 | {
24 | LabelNames = new[]
25 | {
26 | "service", "type", "target", "name", "operation_name", "success", "resultCode"
27 | },
28 | Buckets = new[] { 0.008, 0.016, 0.032, 0.064, 0.128, 0.512, 1, 4, 16 }
29 | });
30 | }
31 |
32 | private static Histogram RequestHistogramFactory(IMetricFactory metrics)
33 | {
34 | return metrics.CreateHistogram(
35 | "ai_request_duration_seconds",
36 | "The duration of request",
37 | new HistogramConfiguration
38 | {
39 | LabelNames = new[] { "service", "name", "success", "resultCode" },
40 | Buckets = new[] { 0.008, 0.016, 0.032, 0.064, 0.128, 0.512, 1, 4, 16 }
41 | });
42 | }
43 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.Prometheus/StartupExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.ApplicationInsights.Extensibility;
2 | using Microsoft.Extensions.Configuration;
3 | using Microsoft.Extensions.DependencyInjection;
4 |
5 | namespace Allegro.Extensions.ApplicationInsights.Prometheus;
6 |
7 | ///
8 | /// IServiceCollection extensions
9 | ///
10 | public static class StartupExtensions
11 | {
12 | ///
13 | /// Add export of application insights telemetry to prometheus metrics
14 | ///
15 | public static IServiceCollection AddApplicationInsightsToPrometheus(
16 | this IServiceCollection services,
17 | IConfiguration configuration)
18 | {
19 | services.AddSingleton();
20 | services.Configure(
21 | configuration.GetSection(ApplicationInsightsToPrometheusMetricsConfig.SectionName));
22 | services.AddSingleton();
23 | return services;
24 | }
25 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/Allegro.Extensions.ApplicationInsights.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
4 | True
5 | True
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.0.0] - 2023-09-27
9 | ### Allegro.Extensions.ApplicationInsights.AspNetCore
10 |
11 | * Initiated Allegro.Extensions.ApplicationInsights.AspNetCore, check readme for features
12 |
13 | ### Allegro.Extensions.ApplicationInsights.Prometheus
14 |
15 | * Initiated Allegro.Extensions.ApplicationInsights.Prometheus, check readme for features
16 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.ApplicationInsights/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.0.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore.Demo/Allegro.Extensions.AspNetCore.Demo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore.Demo/Controllers/SkipOnProdController.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.AspNetCore.Attributes;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace Allegro.Extensions.AspNetCore.Demo.Controllers
5 | {
6 | [ApiController]
7 | [Route("api/skip-on-prod")]
8 | [SkipOnProd]
9 | public class SkipOnProdController : ControllerBase
10 | {
11 | [HttpGet("hello")]
12 | public IActionResult Hello()
13 | {
14 | return Ok("Welcome to test environment! If you see this on production, something went wrong :(");
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore.Demo/Controllers/TestController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 | namespace Allegro.Extensions.AspNetCore.Demo.Controllers
4 | {
5 | [ApiController]
6 | [Route("api/test")]
7 | public class TestController : ControllerBase
8 | {
9 | [HttpGet("hello")]
10 | public IActionResult Hello()
11 | {
12 | return Ok("Welcome to production!");
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore.Demo/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.AspNetCore.Demo
2 | {
3 | public static class Program
4 | {
5 | public static void Main(string[] args)
6 | {
7 | Host.CreateDefaultBuilder(args)
8 | .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup())
9 | .Build()
10 | .Run();
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore.Demo/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Allegro.Extensions.AspNetCore.Demo": {
4 | "commandName": "Project",
5 | "launchBrowser": true,
6 | "launchUrl": "swagger",
7 | "environmentVariables": {
8 | "ASPNETCORE_ENVIRONMENT": "Production",
9 | "Environment": "xyz"
10 | },
11 | "applicationUrl": "https://localhost:5001;http://localhost:5000"
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore.Demo/Startup.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.AspNetCore.Demo.Controllers;
2 | using Allegro.Extensions.AspNetCore.ErrorHandling;
3 | using Allegro.Extensions.AspNetCore.Extensions;
4 |
5 | namespace Allegro.Extensions.AspNetCore.Demo
6 | {
7 | public class Startup
8 | {
9 | private readonly IWebHostEnvironment _env;
10 |
11 | public Startup(IWebHostEnvironment env)
12 | {
13 | _env = env;
14 | }
15 |
16 | public void Configure(IApplicationBuilder app)
17 | {
18 | app
19 | .UseFluentErrorHandlingMiddleware()
20 | .UseRouting()
21 | .UseSwagger()
22 | .UseSwaggerUI()
23 | .UseEndpoints(endpoints => { endpoints.MapControllers(); });
24 | }
25 |
26 | public void ConfigureServices(IServiceCollection services)
27 | {
28 | services
29 | .AddFluentErrorHandlingMiddleware(
30 | logError: error => Console.WriteLine($"Error: {error.Message}"),
31 | logWarning: warning => Console.WriteLine($"Warning: {warning.Message}"),
32 | builder => builder.WithCustomAllegroErrorHandling()
33 | )
34 | .AddControllers()
35 | .AddSkipOnProd(_env)
36 | .AddFluentModelStateValidationHandling(builder => builder.WithCustomAllegroErrorHandling());
37 |
38 | services.AddSwaggerGen();
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore.Tests.Unit/Allegro.Extensions.AspNetCore.Tests.Unit.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | all
17 | runtime; build; native; contentfiles; analyzers; buildtransitive
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1A5C6678-1714-4D2A-A0B5-DF08B4796E92}"
4 | EndProject
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.AspNetCore", "Allegro.Extensions.AspNetCore\Allegro.Extensions.AspNetCore.csproj", "{2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}"
6 | EndProject
7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.AspNetCore.Demo", "Allegro.Extensions.AspNetCore.Demo\Allegro.Extensions.AspNetCore.Demo.csproj", "{B1903BE3-CB8E-44C6-9E68-5D7DFC1C3EE6}"
8 | EndProject
9 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.AspNetCore.Tests.Unit", "Allegro.Extensions.AspNetCore.Tests.Unit\Allegro.Extensions.AspNetCore.Tests.Unit.csproj", "{BBB95FD3-301B-47E9-9F21-4818E55DFFAF}"
10 | EndProject
11 | Global
12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
13 | Debug|Any CPU = Debug|Any CPU
14 | Release|Any CPU = Release|Any CPU
15 | EndGlobalSection
16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
17 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Debug|Any CPU.Build.0 = Debug|Any CPU
19 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Release|Any CPU.ActiveCfg = Release|Any CPU
20 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Release|Any CPU.Build.0 = Release|Any CPU
21 | {B1903BE3-CB8E-44C6-9E68-5D7DFC1C3EE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {B1903BE3-CB8E-44C6-9E68-5D7DFC1C3EE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {B1903BE3-CB8E-44C6-9E68-5D7DFC1C3EE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {B1903BE3-CB8E-44C6-9E68-5D7DFC1C3EE6}.Release|Any CPU.Build.0 = Release|Any CPU
25 | {BBB95FD3-301B-47E9-9F21-4818E55DFFAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {BBB95FD3-301B-47E9-9F21-4818E55DFFAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {BBB95FD3-301B-47E9-9F21-4818E55DFFAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {BBB95FD3-301B-47E9-9F21-4818E55DFFAF}.Release|Any CPU.Build.0 = Release|Any CPU
29 | EndGlobalSection
30 | EndGlobal
31 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.AspNetCore
5 | ...
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore/Attributes/SkipOnProdAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.AspNetCore.Attributes
2 | {
3 | ///
4 | /// Disables the controller on environments other than test (Environment=dev|uat), unless HostEnvironment is Development.
5 | ///
6 | [AttributeUsage(AttributeTargets.Class)]
7 | public class SkipOnProdAttribute : Attribute
8 | {
9 | }
10 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore/ErrorHandling/IErrorSerializer.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.AspNetCore.ErrorHandling;
2 |
3 | ///
4 | /// Defines used by error handling middleware serializer
5 | ///
6 | public interface IErrorSerializer
7 | {
8 | ///
9 | /// Serialize error response
10 | ///
11 | string Serialize(object errorResponse);
12 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore/ErrorHandling/Internals/ErrorResponse.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.AspNetCore.ErrorHandling.Internals;
2 |
3 | internal record ErrorResponse(
4 | string Code,
5 | string Message,
6 | string? UserMessage = default,
7 | string? Path = default,
8 | string? Details = default);
9 |
10 | internal record ErrorResponsesHolder(
11 | IEnumerable Errors);
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore/ErrorHandling/Internals/InvalidModelStateResponseFactory.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Http;
2 | using Microsoft.AspNetCore.Mvc;
3 | using Microsoft.AspNetCore.Mvc.ModelBinding;
4 |
5 | namespace Allegro.Extensions.AspNetCore.ErrorHandling.Internals
6 | {
7 | internal class InvalidModelStateResponseFactory
8 | {
9 | private readonly Func? _customModelStateValidationHandler;
10 |
11 | public InvalidModelStateResponseFactory(Func? customModelStateValidationHandler = null)
12 | {
13 | _customModelStateValidationHandler = customModelStateValidationHandler;
14 | }
15 |
16 | public IActionResult BuildResponse(ActionContext context)
17 | {
18 | var errorResponse = _customModelStateValidationHandler is not null
19 | ? HandleCustomResponse(context)
20 | : DefaultResponse(context);
21 |
22 | return new ObjectResult(errorResponse.Response) { StatusCode = errorResponse.StatusCode };
23 | }
24 |
25 | private static (int StatusCode, object Response) DefaultResponse(ActionContext context)
26 | {
27 | var errorResponseHolder = new ErrorResponsesHolder(
28 | Errors: context.ModelState.Values.Select(
29 | modelStateEntry => new ErrorResponse(
30 | modelStateEntry.ValidationState.ToString(),
31 | GetErrorMessageFrom(modelStateEntry)
32 | )));
33 | return (StatusCodes.Status400BadRequest, errorResponseHolder);
34 | }
35 |
36 | private (int StatusCode, object Response) HandleCustomResponse(ActionContext context)
37 | {
38 | var error = _customModelStateValidationHandler!(context);
39 | return error is not null
40 | ? (error.ResponseCode, error.BuildErrorResponse())
41 | : DefaultResponse(context);
42 | }
43 |
44 | private static string GetErrorMessageFrom(ModelStateEntry value)
45 | {
46 | return string.Join(", ", value.Errors.Select(e => e.ErrorMessage));
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore/ErrorHandling/Internals/SystemTextJsonWebErrorSerializer.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 |
3 | namespace Allegro.Extensions.AspNetCore.ErrorHandling.Internals;
4 |
5 | internal class SystemTextJsonWebErrorSerializer : IErrorSerializer
6 | {
7 | public string Serialize(object errorResponse) =>
8 | JsonSerializer.Serialize(errorResponse, new JsonSerializerOptions(JsonSerializerDefaults.Web));
9 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore/Extensions/MvcBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.AspNetCore.Attributes;
2 | using Allegro.Extensions.AspNetCore.Features;
3 | using Microsoft.Extensions.DependencyInjection;
4 | using Microsoft.Extensions.Hosting;
5 |
6 | namespace Allegro.Extensions.AspNetCore.Extensions
7 | {
8 | ///
9 | /// Asp Mvc Builder Extensions
10 | ///
11 | public static class MvcBuilderExtensions
12 | {
13 | ///
14 | /// Configures the based on `Environment` env variable and ASP.NET hosting environment.
15 | /// Assumes that `IsTestEnv = Environment == dev|uat || HostEnvironment.IsDevelopment()`.
16 | ///
17 | /// IMvcBuilder - target of extension method
18 | /// Hosting environment
19 | /// Allows to override default test environments (dev|uat)
20 | public static IMvcBuilder AddSkipOnProd(
21 | this IMvcBuilder mvcBuilder,
22 | IHostEnvironment aspNetEnvironment,
23 | string[]? overrideTestEnvironments = null)
24 | {
25 | return mvcBuilder
26 | .ConfigureApplicationPartManager(mgr =>
27 | {
28 | mgr.FeatureProviders.Add(
29 | new SkipControllerFeatureProvider(
30 | aspNetEnvironment,
31 | overrideTestEnvironments));
32 | });
33 | }
34 |
35 | ///
36 | /// Configures the .
37 | ///
38 | /// IMvcBuilder - target of extension method
39 | /// Is currently running on test environment
40 | public static IMvcBuilder AddSkipOnProd(this IMvcBuilder mvcBuilder, bool isTestEnv)
41 | {
42 | return mvcBuilder
43 | .ConfigureApplicationPartManager(mgr =>
44 | {
45 | mgr.FeatureProviders.Add(new SkipControllerFeatureProvider(isTestEnv));
46 | });
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/Allegro.Extensions.AspNetCore/InternalsVisibleTo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Allegro.Extensions.AspNetCore.Tests.Unit")]
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.4.0] - 2024-01-11
9 |
10 | ### Added
11 |
12 | * New `AddFluentErrorHandlingMiddleware` overload that allows to pass factories for logging methods.
13 |
14 | ## [1.3.0] - 2022-06-03
15 |
16 | ### Added
17 |
18 | * Default exception handling in controllers with custom error mapping end response provider
19 |
20 | ## [1.2.0] - 2022-05-06
21 |
22 | ### Removed
23 |
24 | * Removed targeting net5.0
25 |
26 | ## [1.1.0] - 2022-03-28
27 |
28 | ### Changed
29 |
30 | * Multitargeting net5.0;net6.0
31 |
32 | ## [1.0.1] - 2022-03-15
33 |
34 | ### Changed
35 |
36 | * Minor code & tests refactor
37 |
38 | ## [1.0.0] - 2022-03-10
39 |
40 | ### Added
41 |
42 | * Initiated Allegro.Extensions.AspNetCore project
43 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.AspNetCore/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.4.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/Allegro.Extensions.Cqrs.Abstractions.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Allegro.Extensions.Cqrs.Abstractions
4 | Contains Cqrs basic abstractions used in Allegro services
5 | true
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/Commands/Command.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Cqrs.Abstractions.Commands;
2 |
3 | ///
4 | /// Cqrs base representation of command.
5 | ///
6 | public abstract record Command
7 | {
8 | ///
9 | /// Command identifier
10 | ///
11 | public string Id { get; } = Guid.NewGuid().ToString();
12 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/Commands/ICommandDispatcher.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Cqrs.Abstractions.Commands;
2 |
3 | ///
4 | /// Cqrs command dispatcher interface
5 | ///
6 | public interface ICommandDispatcher
7 | {
8 | ///
9 | /// Sends command to dispatcher
10 | ///
11 | Task Send(TCommand command) where TCommand : Command;
12 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/Commands/ICommandHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Cqrs.Abstractions.Commands;
2 |
3 | ///
4 | /// Marker interface to add handler for command. In most cases changes state.
5 | ///
6 | public interface ICommandHandler where TCommand : Command
7 | {
8 | ///
9 | /// Handles command request
10 | ///
11 | Task Handle(TCommand command);
12 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/Commands/ICommandValidator.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Cqrs.Abstractions.Commands;
2 |
3 | ///
4 | /// Marker interface that allows to execute more complicated validations before action execution.
5 | ///
6 | /// Supported command type
7 | public interface ICommandValidator where T : Command
8 | {
9 | ///
10 | /// Validates command before execution. Should throw ValidationException or other exception.
11 | ///
12 | Task Validate(T command);
13 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/DecoratorAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Cqrs.Abstractions;
2 |
3 | ///
4 | /// Marker attribute - allows to mark ICommandHandler, IQueryHandler as decorator (pattern) of main handler.
5 | ///
6 | [AttributeUsage(AttributeTargets.Class)]
7 | public class DecoratorAttribute : Attribute
8 | {
9 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/Queries/IQueryDispatcher.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Cqrs.Abstractions.Queries;
2 |
3 | ///
4 | /// Cqrs query dispatcher interface
5 | ///
6 | public interface IQueryDispatcher
7 | {
8 | ///
9 | /// Sends query to dispatcher
10 | ///
11 | /// Type of data returned by query
12 | /// Query data
13 | Task Query(Query query, CancellationToken cancellationToken);
14 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/Queries/IQueryHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Cqrs.Abstractions.Queries;
2 |
3 | ///
4 | /// Cqrs query handler interface
5 | ///
6 | /// Type of supported query
7 | /// Type of data returned by query
8 | public interface IQueryHandler where TQuery : Query
9 | {
10 | ///
11 | /// Handles query execution. In most cases reading data from read-model directly.
12 | ///
13 | Task Handle(TQuery query, CancellationToken cancellationToken);
14 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/Queries/IQueryValidator.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Cqrs.Abstractions.Queries;
2 |
3 | ///
4 | /// Marker interface that allows to execute more complicated validations before action execution.
5 | ///
6 | /// Supported query type
7 | public interface IQueryValidator where T : Query
8 | {
9 | ///
10 | /// Validates query before execution. Should throw ValidationException or other exception.
11 | ///
12 | Task Validate(T query, CancellationToken cancellationToken);
13 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Abstractions/Queries/Query.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Cqrs.Abstractions.Queries;
2 |
3 | ///
4 | /// Cqrs base representation of query.
5 | ///
6 | public abstract record Query
7 | {
8 | ///
9 | /// Query identifier
10 | ///
11 | public string Id { get; } = Guid.NewGuid().ToString();
12 | }
13 |
14 | ///
15 | /// Cqrs base representation of query.
16 | ///
17 | /// Type of data returned by query
18 | public abstract record Query : Query;
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Demo/Allegro.Extensions.Cqrs.Demo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Demo/Commands/BarCommand.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Cqrs.Abstractions;
2 | using Allegro.Extensions.Cqrs.Abstractions.Commands;
3 | using FluentValidation;
4 | using Microsoft.Extensions.Logging;
5 |
6 | namespace Allegro.Extensions.Cqrs.Demo.Commands;
7 |
8 | public record BarCommand(string Name) : Command;
9 |
10 | internal sealed class BarCommandFluentValidator : AbstractValidator
11 | {
12 | public BarCommandFluentValidator()
13 | {
14 | RuleFor(p => p.Name).NotEmpty();
15 | }
16 | }
17 |
18 | internal sealed class BarCommandValidator : ICommandValidator
19 | {
20 | public Task Validate(BarCommand command)
21 | {
22 | if (string.IsNullOrEmpty(command.Name))
23 | {
24 | throw new ValidationException("Missing name!");
25 | }
26 |
27 | return Task.CompletedTask;
28 | }
29 | }
30 |
31 | internal sealed class BarCommandHandler : ICommandHandler
32 | {
33 | private readonly ILogger _logger;
34 |
35 | public BarCommandHandler(ILogger logger)
36 | {
37 | _logger = logger;
38 | }
39 |
40 | public Task Handle(BarCommand command)
41 | {
42 | #pragma warning disable CA1848
43 | _logger.LogInformation("Handle Bar");
44 | #pragma warning restore CA1848
45 | return Task.CompletedTask;
46 | }
47 | }
48 |
49 | [Decorator]
50 | internal sealed class BarCommandHandlerDecorator : ICommandHandler
51 | {
52 | private readonly ICommandHandler _decorated;
53 | private readonly ILogger _logger;
54 |
55 | public BarCommandHandlerDecorator(ICommandHandler decorated, ILogger logger)
56 | {
57 | _decorated = decorated;
58 | _logger = logger;
59 | }
60 |
61 | public async Task Handle(BarCommand command)
62 | {
63 | #pragma warning disable CA1848
64 | _logger.LogInformation("Before handle");
65 | await _decorated.Handle(command);
66 | _logger.LogInformation("After handle");
67 | #pragma warning restore CA1848
68 | }
69 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Demo/Controllers/CommandController.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Cqrs.Abstractions.Commands;
2 | using Allegro.Extensions.Cqrs.Demo.Commands;
3 | using Microsoft.AspNetCore.Mvc;
4 |
5 | namespace Allegro.Extensions.Cqrs.Demo.Controllers;
6 |
7 | [ApiController]
8 | [Route("commands")]
9 | public class CommandController : ControllerBase
10 | {
11 | private readonly ICommandDispatcher _commandDispatcher;
12 |
13 | public CommandController(ICommandDispatcher commandDispatcher)
14 | {
15 | _commandDispatcher = commandDispatcher;
16 | }
17 |
18 | [HttpPost("bar")]
19 | public async Task Bar(BarCommand command)
20 | {
21 | await _commandDispatcher.Send(command);
22 | return Ok(command.Id);
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Demo/Controllers/QueryController.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Cqrs.Abstractions.Queries;
2 | using Allegro.Extensions.Cqrs.Demo.Queries;
3 | using Microsoft.AspNetCore.Mvc;
4 |
5 | namespace Allegro.Extensions.Cqrs.Demo.Controllers;
6 |
7 | [ApiController]
8 | [Route("queries")]
9 | public class QueryController : ControllerBase
10 | {
11 | private readonly IQueryDispatcher _queryDispatcher;
12 |
13 | public QueryController(IQueryDispatcher queryDispatcher)
14 | {
15 | _queryDispatcher = queryDispatcher;
16 | }
17 |
18 | [HttpGet("bar")]
19 | public async Task Bar([FromQuery] string? id, CancellationToken cancellationToken)
20 | {
21 | var result = await _queryDispatcher.Query(new BarQuery(id), cancellationToken);
22 | return Ok(result);
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Demo/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Cqrs.Demo;
2 |
3 | public static class Program
4 | {
5 | public static void Main(string[] args)
6 | {
7 | Host.CreateDefaultBuilder(args)
8 | .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup())
9 | .Build()
10 | .Run();
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Demo/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Allegro.Extensions.Cqrs.Demo": {
4 | "commandName": "Project",
5 | "launchBrowser": true,
6 | "launchUrl": "swagger",
7 | "environmentVariables": {
8 | "ASPNETCORE_ENVIRONMENT": "Production"
9 | },
10 | "applicationUrl": "https://localhost:5001;http://localhost:5000"
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Demo/Queries/BarQuery.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Cqrs.Abstractions;
2 | using Allegro.Extensions.Cqrs.Abstractions.Queries;
3 | using Allegro.Extensions.Cqrs.Demo.Commands;
4 | using FluentValidation;
5 | using Microsoft.Extensions.Logging;
6 |
7 | namespace Allegro.Extensions.Cqrs.Demo.Queries;
8 |
9 | public record BarData(string SomeData);
10 | internal sealed record BarQuery(string? SomeId) : Query;
11 |
12 | internal sealed class BarQueryFluentValidator : AbstractValidator
13 | {
14 | public BarQueryFluentValidator()
15 | {
16 | RuleFor(p => p.SomeId).NotEmpty();
17 | }
18 | }
19 |
20 | internal sealed class BarQueryValidator : IQueryValidator
21 | {
22 | public Task Validate(BarQuery query, CancellationToken cancellationToken)
23 | {
24 | if (string.IsNullOrEmpty(query.SomeId))
25 | {
26 | throw new ValidationException("Missing some id!");
27 | }
28 |
29 | return Task.CompletedTask;
30 | }
31 | }
32 |
33 | internal sealed class BarQueryHandler : IQueryHandler
34 | {
35 | public Task Handle(BarQuery query, CancellationToken cancellationToken)
36 | {
37 | // should take data directly from read model on dedicates sql query to view of some data
38 | return Task.FromResult(new BarData("Some data 1"));
39 | }
40 | }
41 |
42 | [Decorator]
43 | internal sealed class BarQueryHandlerDecorator : IQueryHandler
44 | {
45 | private readonly IQueryHandler _decorated;
46 | private readonly ILogger _logger;
47 |
48 | public BarQueryHandlerDecorator(IQueryHandler decorated, ILogger logger)
49 | {
50 | _decorated = decorated;
51 | _logger = logger;
52 | }
53 |
54 | public async Task Handle(BarQuery query, CancellationToken cancellationToken)
55 | {
56 | #pragma warning disable CA1848
57 | _logger.LogInformation("Before handle");
58 | var result = await _decorated.Handle(query, cancellationToken);
59 | _logger.LogInformation("After handle");
60 | #pragma warning restore CA1848
61 | return result;
62 | }
63 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Demo/Startup.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Cqrs.Abstractions.Commands;
2 | using Allegro.Extensions.Cqrs.Abstractions.Queries;
3 | using Allegro.Extensions.Cqrs.Commands;
4 | using Allegro.Extensions.Cqrs.Demo.Commands;
5 | using Allegro.Extensions.Cqrs.Demo.Queries;
6 | using Allegro.Extensions.Cqrs.FluentValidations;
7 | using Allegro.Extensions.Cqrs.Queries;
8 |
9 | namespace Allegro.Extensions.Cqrs.Demo;
10 |
11 | public class Startup
12 | {
13 | private readonly IWebHostEnvironment _env;
14 |
15 | public Startup(IWebHostEnvironment env)
16 | {
17 | _env = env;
18 | }
19 |
20 | public void Configure(IApplicationBuilder app)
21 | {
22 | app
23 | .UseRouting()
24 | .UseSwagger()
25 | .UseSwaggerUI()
26 | .UseEndpoints(endpoints => { endpoints.MapControllers(); });
27 | }
28 |
29 | public void ConfigureServices(IServiceCollection services)
30 | {
31 | var cqrsAssemblies = new[] { typeof(Startup).Assembly };
32 | services
33 | .AddCommands(cqrsAssemblies)
34 | .AddQueries(cqrsAssemblies)
35 | .AddCqrsFluentValidations(cqrsAssemblies)
36 | .AddControllers();
37 | services.TryDecorate, BarCommandHandlerDecorator>();
38 | services.TryDecorate, BarQueryHandlerDecorator>();
39 | services.AddSwaggerGen();
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.FluentValidations/Allegro.Extensions.Cqrs.FluentValidations.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Allegro.Extensions.Cqrs.FluentValidations
4 | Contains FluentVlidations extension for Allegro.Extensions.Cqrs
5 | true
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.FluentValidations/FluentCommandValidator.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Cqrs.Abstractions.Commands;
2 | using FluentValidation;
3 | using Microsoft.Extensions.DependencyInjection;
4 |
5 | namespace Allegro.Extensions.Cqrs.FluentValidations;
6 |
7 | internal sealed class FluentCommandValidator : ICommandValidator
8 | where T : Command
9 | {
10 | private readonly IServiceProvider _serviceProvider;
11 |
12 | public FluentCommandValidator(IServiceProvider serviceProvider)
13 | {
14 | _serviceProvider = serviceProvider;
15 | }
16 |
17 | public async Task Validate(T command)
18 | {
19 | var requestValidators = _serviceProvider.GetServices>();
20 |
21 | var failures = (await Task.WhenAll(requestValidators.Select(v => v.ValidateAsync(command))))
22 | .SelectMany(result => result.Errors)
23 | .Where(f => f != null)
24 | .ToList();
25 |
26 | if (failures.Count != 0)
27 | {
28 | throw new ValidationException(failures);
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.FluentValidations/FluentQueryValidator.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Cqrs.Abstractions.Queries;
2 | using FluentValidation;
3 | using Microsoft.Extensions.DependencyInjection;
4 |
5 | namespace Allegro.Extensions.Cqrs.FluentValidations;
6 |
7 | internal sealed class FluentQueryValidator : IQueryValidator
8 | where T : Query
9 | {
10 | private readonly IServiceProvider _serviceProvider;
11 |
12 | public FluentQueryValidator(IServiceProvider serviceProvider)
13 | {
14 | _serviceProvider = serviceProvider;
15 | }
16 |
17 | public async Task Validate(T query, CancellationToken cancellationToken)
18 | {
19 | var requestValidators = _serviceProvider.GetServices>();
20 |
21 | var failures = (await Task.WhenAll(requestValidators.Select(v => v.ValidateAsync(query, cancellationToken))))
22 | .SelectMany(result => result.Errors)
23 | .Where(f => f != null)
24 | .ToList();
25 |
26 | if (failures.Count != 0)
27 | {
28 | throw new ValidationException(failures);
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.FluentValidations/StartupExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using Allegro.Extensions.Cqrs.Abstractions.Commands;
3 | using Allegro.Extensions.Cqrs.Abstractions.Queries;
4 | using FluentValidation;
5 | using Microsoft.Extensions.DependencyInjection;
6 |
7 | namespace Allegro.Extensions.Cqrs.FluentValidations;
8 |
9 | ///
10 | /// Startup Extensions - expose registration of Fluent Validations for CQRS in application.
11 | ///
12 | public static class StartupExtensions
13 | {
14 | ///
15 | /// Add fluent validations for CQRS and register all IValidator from given assemblies
16 | ///
17 | ///
18 | /// Assembly collection in which IValidators should be looked for.
19 | /// Determines whether only public classes should be registered
20 | public static IServiceCollection AddCqrsFluentValidations(
21 | this IServiceCollection services,
22 | IEnumerable assemblies,
23 | bool publicOnly = false)
24 | {
25 | services.Scan(s => s.FromAssemblies(assemblies)
26 | .AddClasses(c => c.AssignableTo(typeof(IValidator<>)), publicOnly)
27 | .AsImplementedInterfaces()
28 | .WithScopedLifetime());
29 |
30 | services
31 | .Scan(s => s.FromCallingAssembly()
32 | .AddClasses(
33 | c => c.AssignableToAny(typeof(ICommandValidator<>), typeof(IQueryValidator<>)),
34 | publicOnly)
35 | .AsImplementedInterfaces()
36 | .WithScopedLifetime());
37 |
38 | return services;
39 | }
40 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.Tests.Unit/Allegro.Extensions.Cqrs.Tests.Unit.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | true
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | all
16 | runtime; build; native; contentfiles; analyzers; buildtransitive
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Allegro.Extensions.Cqrs
4 | Contains Cqrs defualt implementation of automatic registration, default dispatchers and command actions support used in Allegro services
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs/Commands/CommandDispatcher.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Cqrs.Abstractions.Commands;
2 | using Microsoft.Extensions.DependencyInjection;
3 |
4 | namespace Allegro.Extensions.Cqrs.Commands;
5 |
6 | // TODO: can we extract common logic for command and query? Should we?
7 | internal sealed class CommandDispatcher : ICommandDispatcher
8 | {
9 | private readonly IServiceProvider _serviceProvider;
10 |
11 | public CommandDispatcher(IServiceProvider serviceProvider)
12 | => _serviceProvider = serviceProvider;
13 |
14 | public async Task Send(TCommand command) where TCommand : Command
15 | {
16 | // TODO: maybe some configuration to reuse outer scope instead of creating new one
17 | using var scope = _serviceProvider.CreateScope();
18 |
19 | var commandValidators = scope.ServiceProvider.GetServices>();
20 |
21 | await Task.WhenAll(commandValidators.Select(p => p.Validate(command)));
22 |
23 | var handlers = scope.ServiceProvider.GetServices>().ToList();
24 |
25 | // TODO: throw this on startup
26 | if (handlers.Count == 0)
27 | throw new MissingCommandHandlerException(command);
28 |
29 | if (handlers.Count > 1)
30 | throw new MultipleCommandHandlerException(command);
31 |
32 | var handler = handlers.Single();
33 |
34 | await handler.Handle(command);
35 | }
36 | }
37 |
38 | internal class MissingCommandHandlerException : Exception
39 | {
40 | public MissingCommandHandlerException(Command command) : base($"Missing handler for command {command.GetType().FullName}")
41 | {
42 | }
43 | }
44 |
45 | internal class MultipleCommandHandlerException : Exception
46 | {
47 | public MultipleCommandHandlerException(Command command) : base($"Multiple handler registration for command {command.GetType().FullName}")
48 | {
49 | }
50 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs/Commands/StartupExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using Allegro.Extensions.Cqrs.Abstractions;
3 | using Allegro.Extensions.Cqrs.Abstractions.Commands;
4 | using Microsoft.Extensions.DependencyInjection;
5 |
6 | namespace Allegro.Extensions.Cqrs.Commands;
7 |
8 | ///
9 | /// Startup Extensions - expose registration of commands in application.
10 | ///
11 | public static class StartupExtensions
12 | {
13 | ///
14 | /// Register all commands/handlers implemented in application and common tools (dispatchers, actions, validators)
15 | ///
16 | ///
17 | /// Assembly collection in which Command related types should be looked for.
18 | /// Determines whether only public classes should be registered
19 | public static IServiceCollection AddCommands(
20 | this IServiceCollection services,
21 | IEnumerable assemblies,
22 | bool publicOnly = false)
23 | {
24 | services
25 | .AddSingleton();
26 | services
27 | .Scan(s => s.FromAssemblies(assemblies) // TODO: should we remove Scrutor in future?
28 | .AddClasses(
29 | c => c.AssignableTo(typeof(ICommandHandler<>))
30 | .WithoutAttribute(),
31 | publicOnly)
32 | .AsImplementedInterfaces()
33 | .WithScopedLifetime());
34 |
35 | services
36 | .Scan(s => s.FromAssemblies(assemblies)
37 | .AddClasses(c => c.AssignableTo(typeof(ICommandValidator<>)), publicOnly)
38 | .AsImplementedInterfaces()
39 | .WithScopedLifetime());
40 | return services;
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs/InternalsVisibleTo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) PlaceholderCompany. All rights reserved.
2 |
3 | using System.Runtime.CompilerServices;
4 |
5 | [assembly: InternalsVisibleTo("Allegro.Extensions.Cqrs.Tests.Unit")]
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/Allegro.Extensions.Cqrs/Queries/StartupExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using Allegro.Extensions.Cqrs.Abstractions;
3 | using Allegro.Extensions.Cqrs.Abstractions.Queries;
4 | using Microsoft.Extensions.DependencyInjection;
5 |
6 | namespace Allegro.Extensions.Cqrs.Queries;
7 |
8 | ///
9 | /// Startup Extensions - expose registration of queries in application.
10 | ///
11 | public static class StartupExtensions
12 | {
13 | ///
14 | /// Register all queries/handlers implemented in application and common tools (dispatchers)
15 | ///
16 | ///
17 | /// Assembly collection in which Command related types should be looked for.
18 | /// Determines whether only public classes should be registered
19 | public static IServiceCollection AddQueries(this IServiceCollection services, IEnumerable assemblies, bool publicOnly = false)
20 | {
21 | services.AddSingleton();
22 | services.Scan(s => s.FromAssemblies(assemblies) // TODO: remove scrutor and register by own util
23 | .AddClasses(
24 | c => c.AssignableTo(typeof(IQueryHandler<,>))
25 | .WithoutAttribute(),
26 | publicOnly)
27 | .AsImplementedInterfaces()
28 | .WithScopedLifetime());
29 |
30 | services
31 | .Scan(s => s.FromAssemblies(assemblies)
32 | .AddClasses(c => c.AssignableTo(typeof(IQueryValidator<>)), publicOnly)
33 | .AsImplementedInterfaces()
34 | .WithScopedLifetime());
35 | return services;
36 | }
37 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [2.2.0] - 2025-01-14
9 | ### Allegro.Extensions.Cqrs
10 | - Added publicOnly parameter to AddQueries and AddCommands methods
11 | - Unified commands/queries registration behavior across different Scrutor versions
12 | ### Allegro.Extensions.Cqrs.FluentValidations
13 | - Added publicOnly parameter to AddCqrsFluentValidations method
14 | - Unified validators registration behavior across different Scrutor versions
15 |
16 | ## [2.1.0] - 2023-01-26
17 |
18 | ### Allegro.Extensions.Cqrs
19 |
20 | Command and Query dispatchers will explicitly fail when multiple handler registrations are registered.
21 |
22 | ## [2.0.0] - 2023-01-26
23 |
24 | ### Allegro.Extensions.Cqrs.Abstractions
25 |
26 | Replace ICommand and IQuery with Command and Query (based on the approach
27 | from [CQRS.Mediatr.Lite](https://github.com/microsoft/CQRS.Mediatr.Lite/blob/a6f63cf62a5e2b1b48a55b7917ba036c8ae6f3b9/src/sdk/Command/Command.cs))
28 |
29 | ## [1.1.0] - 2022-11-17
30 |
31 | ### Allegro.Extensions.Cqrs
32 |
33 | * Adjust implementation to Allegro.Extensions.Cqrs.Abstractions 1.1.0
34 | * Some code cleanup
35 |
36 | ### Allegro.Extensions.Cqrs.Abstractions
37 |
38 | * Remove ICommandExecutionActions - as we already have possibility to decorate
39 | * Add IQueryValidator
40 | * Change query result not nullable
41 |
42 | ### Allegro.Extensions.Cqrs.FluentValidations
43 |
44 | * Add `AddCqrsFluentValidations` extension to enable fluent validations
45 |
46 | ## [1.0.0] - 2022-11-09
47 | ### Allegro.Extensions.Cqrs
48 |
49 | * Initiated Allegro.Extensions.Cqrs with default implementation of dispatchers and command actions support
50 |
51 | ### Allegro.Extensions.Cqrs.Abstractions
52 |
53 | * Initiated Allegro.Extensions.Cqrs.Abstractions with basic abstraction for cqrs.
54 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Cqrs/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2.2.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres.Tests.Integration/Allegro.Extensions.Dapper.Postgres.Tests.Integration.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
22 |
23 |
24 | PreserveNewest
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres.Tests.Integration/Helpers/CustomWebApplicationFactory.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Hosting;
2 | using Microsoft.AspNetCore.Mvc.Testing;
3 | using Microsoft.AspNetCore.TestHost;
4 | using Microsoft.Extensions.Configuration;
5 | using Microsoft.Extensions.Hosting;
6 |
7 | namespace Allegro.Extensions.Dapper.Postgres.Tests.Integration.Helpers;
8 |
9 | public class CustomWebApplicationFactory : WebApplicationFactory
10 | {
11 | protected override IHostBuilder CreateHostBuilder()
12 | {
13 | return base.CreateHostBuilder()!
14 | .ConfigureAppConfiguration((_, builder) =>
15 | {
16 | builder
17 | .SetBasePath(Directory.GetCurrentDirectory())
18 | .AddJsonFile("appsettings.Test.json");
19 | })
20 | .ConfigureWebHostDefaults(
21 | webBuilder =>
22 | {
23 | webBuilder
24 | .UseTestServer()
25 | .UseStartup();
26 | })
27 | .UseEnvironment(Environments.Development);
28 | }
29 |
30 | protected override IHost CreateHost(IHostBuilder builder)
31 | {
32 | builder.UseContentRoot(Directory.GetCurrentDirectory());
33 | return base.CreateHost(builder);
34 | }
35 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres.Tests.Integration/Helpers/FakeStartup.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Dapper.Extensions;
2 | using Allegro.Extensions.Dapper.Postgres.Extensions;
3 | using Microsoft.AspNetCore.Builder;
4 | using Microsoft.AspNetCore.Hosting;
5 | using Microsoft.Extensions.Configuration;
6 | using Microsoft.Extensions.DependencyInjection;
7 |
8 | namespace Allegro.Extensions.Dapper.Postgres.Tests.Integration.Helpers;
9 |
10 | public class FakeStartup
11 | {
12 | private readonly IConfiguration _configuration;
13 |
14 | public FakeStartup(IConfiguration configuration)
15 | {
16 | _configuration = configuration;
17 | }
18 |
19 | public void ConfigureServices(IServiceCollection services)
20 | {
21 | var connectionString = _configuration["PostgresSDK:ConnectionString"];
22 |
23 | services
24 | .AddDapperClient()
25 | .AddDapperPostgres(connectionString);
26 | }
27 |
28 | public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
29 | {
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres.Tests.Integration/Helpers/SqlQueries.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Dapper.Postgres.Tests.Integration.Helpers;
2 |
3 | public static class SqlQueries
4 | {
5 | public const string TableName = "TestTable";
6 |
7 | public static string CreateTableIfNotExists =>
8 | @"
9 | CREATE TABLE IF NOT EXISTS TestTable
10 | (
11 | Id SERIAL primary key,
12 | Username VARCHAR(40) UNIQUE
13 | );
14 | ";
15 |
16 | public static string InsertRowWithReturning =>
17 | $@"
18 | INSERT INTO {TableName}
19 | (
20 | Username
21 | )
22 | VALUES
23 | (
24 | @Username
25 | )
26 | RETURNING
27 | id AS Id,
28 | username AS Username;
29 | ";
30 |
31 | public static string DropTableIfExists =>
32 | $@"DROP TABLE IF EXISTS {TableName}";
33 |
34 | public static string SelectAllFromTable =>
35 | $@"SELECT
36 | Id,
37 | Username
38 | FROM {TableName}";
39 |
40 | public static string SelectFirstFromTable =>
41 | SelectAllFromTable + " LIMIT 1";
42 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres.Tests.Integration/Models/TestModel.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | namespace Vabank.Storage.Postgres.Sdk.Tests.Integration.Models;
3 |
4 | public class TestModel
5 | {
6 | public TestModel(int id, string? username)
7 | {
8 | Id = id;
9 | Username = username;
10 | }
11 |
12 | public int Id { get; set; }
13 | public string? Username { get; set; }
14 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres.Tests.Integration/appsettings.Test.json:
--------------------------------------------------------------------------------
1 | {
2 | "PostgresSDK": {
3 | "ConnectionString" : "TODO"
4 | }
5 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres/Abstractions/DbType.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 |
3 | #pragma warning disable CS1591
4 | namespace Allegro.Extensions.Dapper.Postgres.Abstractions;
5 |
6 | ///
7 | /// Dto database type.
8 | ///
9 | [SuppressMessage("Naming", "CA1720:Identifier contains type name", Justification = "Purpose of that enum")]
10 | public enum DbType
11 | {
12 | Int,
13 | BigInt,
14 | Text,
15 | Date,
16 | Decimal,
17 | Guid,
18 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres/Abstractions/IDapperPostgresBinaryCopyClient.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Dapper.Postgres.Exceptions;
2 |
3 | namespace Allegro.Extensions.Dapper.Postgres.Abstractions;
4 |
5 | ///
6 | /// Binary copy operation using built-in Postgres mechanism.
7 | ///
8 | public interface IDapperPostgresBinaryCopyClient
9 | {
10 | ///
11 | /// Binary COPY FROM operation which is data import mechanism to a Postgres table.
12 | ///
13 | /// Table name to which data will be copied
14 | /// Dictionary of name and type of columns
15 | /// Selector of properties to copy from source data type
16 | /// Source data
17 | /// Source data type
18 | /// Number of affected rows
19 | /// Thrown if there is a DbConnection type mismatch
20 | /// from IDatabaseConnectionFactory
21 | public Task BinaryCopyAsync(
22 | string tableName,
23 | IDictionary columns,
24 | Func selector,
25 | IAsyncEnumerable source);
26 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres/Allegro.Extensions.Dapper.Postgres.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.Dapper.Postgres
5 | Postgres Dapper clients
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres/Exceptions/InvalidDbConnectionTypeException.cs:
--------------------------------------------------------------------------------
1 | #pragma warning disable CS1591
2 |
3 | namespace Allegro.Extensions.Dapper.Postgres.Exceptions;
4 |
5 | ///
6 | /// Exception which indicates invalid underlying DbConnection type.
7 | ///
8 | public class InvalidDbConnectionTypeException : Exception
9 | {
10 | public InvalidDbConnectionTypeException(string expectedType)
11 | : base($"Invalid DbConnectionType, expected type: {expectedType}")
12 | {
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres/Extensions/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Dapper.Abstractions;
2 | using Allegro.Extensions.Dapper.Configurations;
3 | using Allegro.Extensions.Dapper.Postgres.Abstractions;
4 | using Allegro.Extensions.Dapper.Postgres.Factories;
5 | using Microsoft.Extensions.DependencyInjection;
6 |
7 | namespace Allegro.Extensions.Dapper.Postgres.Extensions;
8 |
9 | ///
10 | /// Service Collection Extensions to register dapper postgress services
11 | ///
12 | public static class ServiceCollectionExtensions
13 | {
14 | ///
15 | /// Register Dapper Postgres utilities with passed connection string as a parameter.
16 | ///
17 | /// Target of an extension method
18 | /// Postgres database connection string
19 | public static IServiceCollection AddDapperPostgres(
20 | this IServiceCollection services,
21 | string connectionString)
22 | {
23 | if (string.IsNullOrWhiteSpace(connectionString))
24 | {
25 | throw new ArgumentNullException(nameof(connectionString), "Empty connection string");
26 | }
27 |
28 | return services
29 | .AddSingleton(new DatabaseConfiguration
30 | {
31 | ConnectionString = connectionString
32 | })
33 | .AddSingleton()
34 | .AddSingleton()
35 | .AddSingleton();
36 | }
37 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.Postgres/Factories/PostgresDatabaseConnectionFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Data.Common;
2 | using Allegro.Extensions.Dapper.Abstractions;
3 | using Allegro.Extensions.Dapper.Configurations;
4 | using Npgsql;
5 |
6 | namespace Allegro.Extensions.Dapper.Postgres.Factories;
7 |
8 | ///
9 | /// Database connection factory for Postgres database.
10 | ///
11 | internal class PostgresDatabaseConnectionFactory : IDatabaseConnectionFactory
12 | {
13 | private readonly DatabaseConfiguration _databaseConfiguration;
14 |
15 | public PostgresDatabaseConnectionFactory(
16 | DatabaseConfiguration databaseConfiguration)
17 | {
18 | _databaseConfiguration = databaseConfiguration;
19 | }
20 |
21 | ///
22 | /// Initialize new NpgsqlConnection with registered as configuration connection string.
23 | ///
24 | public DbConnection Create() =>
25 | new NpgsqlConnection(_databaseConfiguration.ConnectionString);
26 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1A5C6678-1714-4D2A-A0B5-DF08B4796E92}"
3 | EndProject
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Dapper", "Allegro.Extensions.Dapper\Allegro.Extensions.Dapper.csproj", "{2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Dapper.Postgres", "Allegro.Extensions.Dapper.Postgres\Allegro.Extensions.Dapper.Postgres.csproj", "{C4EBC25F-22C8-4F15-AA21-53567F3269BF}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Dapper.Postgres.Tests.Integration", "Allegro.Extensions.Dapper.Postgres.Tests.Integration\Allegro.Extensions.Dapper.Postgres.Tests.Integration.csproj", "{B1B1FADB-D3DF-4FD6-A2A2-EE3821C6ED79}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {C4EBC25F-22C8-4F15-AA21-53567F3269BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {C4EBC25F-22C8-4F15-AA21-53567F3269BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {C4EBC25F-22C8-4F15-AA21-53567F3269BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {C4EBC25F-22C8-4F15-AA21-53567F3269BF}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {B1B1FADB-D3DF-4FD6-A2A2-EE3821C6ED79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {B1B1FADB-D3DF-4FD6-A2A2-EE3821C6ED79}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {B1B1FADB-D3DF-4FD6-A2A2-EE3821C6ED79}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {B1B1FADB-D3DF-4FD6-A2A2-EE3821C6ED79}.Release|Any CPU.Build.0 = Release|Any CPU
28 | EndGlobalSection
29 | EndGlobal
30 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper/Abstractions/IDatabaseConnectionFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Data.Common;
2 |
3 | namespace Allegro.Extensions.Dapper.Abstractions;
4 |
5 | ///
6 | /// Factory to create specific DbConnection (e. g. Postgres, MySQL DbConnection).
7 | ///
8 | public interface IDatabaseConnectionFactory
9 | {
10 | ///
11 | /// Initialize database connection with registered as configuration connection string.
12 | ///
13 | DbConnection Create();
14 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.Dapper
5 | Dapper utilities
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper/Configurations/DatabaseConfiguration.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Dapper.Configurations;
2 |
3 | ///
4 | /// Database configuration options.
5 | ///
6 | public class DatabaseConfiguration
7 | {
8 | ///
9 | /// Connection string to a database.
10 | ///
11 | public string ConnectionString { get; init; } = null!;
12 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/Allegro.Extensions.Dapper/Extensions/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Dapper.Abstractions;
2 | using Microsoft.Extensions.DependencyInjection;
3 |
4 | namespace Allegro.Extensions.Dapper.Extensions;
5 |
6 | ///
7 | /// Service Collection Extensions
8 | ///
9 | public static class ServiceCollectionExtensions
10 | {
11 | ///
12 | /// Register Dapper Client.
13 | ///
14 | /// Target of an extension method
15 | public static IServiceCollection AddDapperClient(
16 | this IServiceCollection services)
17 | {
18 | return services
19 | .AddSingleton();
20 | }
21 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.2.0] - 2022-10-26
9 |
10 | ### Added
11 |
12 | * Add support for uuid type in binary copy client.
13 |
14 | ## [1.1.0] - 2022-05-06
15 |
16 | ### Removed
17 |
18 | * Removed targeting net5.0
19 |
20 | ## [1.0.0] - 2022-05-06
21 |
22 | ### Added
23 |
24 | * Initiated Allegro.Extensions.Dapper project
25 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Dapper/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.2.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/Allegro.Extensions.DependencyCall.Abstractions/Allegro.Extensions.DependencyCall.Abstractions.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Allegro.Extensions.DependencyCall.Abstractions
4 | Contains DependencyCall package abstractions
5 | ${NoWarn},CS8618,SA1636
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/Allegro.Extensions.DependencyCall.Abstractions/IDependencyCallDispatcher.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.DependencyCall.Abstractions;
2 |
3 | ///
4 | /// Allows to dispatch any dependency call with default pipeline.
5 | ///
6 | public interface IDependencyCallDispatcher
7 | {
8 | ///
9 | /// Dispatches IRequest with default pipeline and support for metrics, fallbacks, retry policies.
10 | ///
11 | /// Request data
12 | /// Optional cancellation token. If null default cancellation policy will be used
13 | /// Type of response data
14 | Task Dispatch(IRequest request, CancellationToken cancellationToken = default);
15 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/Allegro.Extensions.DependencyCall.Abstractions/IDependencyCallMetrics.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.DependencyCall.Abstractions;
2 |
3 | ///
4 | /// Expose metrics collected by dispatcher. Allow to support own implementation of metrics
5 | ///
6 | public interface IDependencyCallMetrics
7 | {
8 | ///
9 | /// Triggered when new dependency call was executed successfully
10 | ///
11 | public void Succeeded(IRequest request, TimeSpan duration);
12 |
13 | ///
14 | /// Triggered when new dependency call failed with error
15 | ///
16 | public void Failed(IRequest request, Exception exception, TimeSpan duration);
17 |
18 | ///
19 | /// Triggered when new dependency call used fallback
20 | ///
21 | public void Fallback(IRequest request, TimeSpan duration);
22 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/Allegro.Extensions.DependencyCall.Abstractions/IRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.DependencyCall.Abstractions;
2 |
3 | ///
4 | /// Marker interface. Used to recognize Dependency Call request data
5 | ///
6 | /// Type of dependency call response data
7 | public interface IRequest : IRequest
8 | {
9 | }
10 |
11 | ///
12 | /// Marker interface. Used to recognize Dependency Call request data
13 | ///
14 | public interface IRequest { }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/Allegro.Extensions.DependencyCall.Metrics.Prometheus/Allegro.Extensions.DependencyCall.Metrics.Prometheus.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Allegro.Extensions.DependencyCall.Metrics.Prometheus
4 | Contains prometheus based metrics for dependency call
5 | ${NoWarn},CS8618,SA1636
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/Allegro.Extensions.DependencyCall.Metrics.Prometheus/DependencyCallBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 |
3 | namespace Allegro.Extensions.DependencyCall.Metrics.Prometheus;
4 |
5 | ///
6 | /// Register Prometheus metrics extensions
7 | ///
8 | public static class DependencyCallBuilderExtensions
9 | {
10 | ///
11 | /// Registers PrometheusDependencyCallMetrics into DependencyCall pipeline
12 | ///
13 | public static DependencyCallBuilder RegisterPrometheusDependencyCallMetrics(
14 | this DependencyCallBuilder builder,
15 | string applicationName)
16 | {
17 | builder.Services.AddSingleton(sp => new ApplicationNameProvider(applicationName));
18 | return builder.WithDependencyCallMetrics();
19 | }
20 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/Allegro.Extensions.DependencyCall.Metrics.Prometheus/PrometheusDependencyCallMetrics.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.DependencyCall.Abstractions;
2 | using Prometheus;
3 |
4 | namespace Allegro.Extensions.DependencyCall.Metrics.Prometheus;
5 |
6 | internal class PrometheusDependencyCallMetrics : IDependencyCallMetrics
7 | {
8 | private readonly Histogram _dependencyCallDuration;
9 |
10 | public PrometheusDependencyCallMetrics(IMetricFactory metrics, ApplicationNameProvider applicationNameProvider)
11 | {
12 | _dependencyCallDuration = DependencyCallDurationFactory(metrics, applicationNameProvider.ApplicationName);
13 | }
14 |
15 | private static Histogram DependencyCallDurationFactory(IMetricFactory metrics, string applicationName) =>
16 | metrics.CreateHistogram(
17 | $"{applicationName}_dependency_call_duration_metrics",
18 | "Duration of dependency call",
19 | new HistogramConfiguration()
20 | {
21 | // CA1861 : Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array
22 | #pragma warning disable CA1861
23 | LabelNames = new[] { "dependencyCallName", "type" },
24 | #pragma warning restore CA1861
25 | Buckets = new[] { 0.008, 0.016, 0.032, 0.064, 0.128, 0.512, 1, 4, 16 },
26 | });
27 |
28 | public void Succeeded(IRequest request, TimeSpan duration)
29 | {
30 | _dependencyCallDuration.WithLabels(request.GetType().FullName!, "succeeded")
31 | .Observe(duration.TotalSeconds);
32 | }
33 |
34 | public void Failed(IRequest request, Exception exception, TimeSpan duration)
35 | {
36 | _dependencyCallDuration.WithLabels(request.GetType().FullName!, "failed").Observe(duration.TotalSeconds);
37 | }
38 |
39 | public void Fallback(IRequest request, TimeSpan duration)
40 | {
41 | _dependencyCallDuration.WithLabels(request.GetType().FullName!, "fallback")
42 | .Observe(duration.TotalSeconds);
43 | }
44 | }
45 |
46 | internal record ApplicationNameProvider(string ApplicationName);
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/Allegro.Extensions.DependencyCall.Tests.Unit/Allegro.Extensions.DependencyCall.Tests.Unit.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | ${NoWarn},CS8618,CS1591
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/Allegro.Extensions.DependencyCall/Allegro.Extensions.DependencyCall.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.DependencyCall
5 | Contains DependencyCall tool
6 | ${NoWarn},CS8618,SA1636
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/Allegro.Extensions.DependencyCall/NoOperationDependencyCallMetrics.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using Allegro.Extensions.DependencyCall.Abstractions;
3 |
4 | namespace Allegro.Extensions.DependencyCall;
5 |
6 | [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Interface implementation")]
7 | internal class NoOperationDependencyCallMetrics : IDependencyCallMetrics
8 | {
9 | public void Succeeded(IRequest request, TimeSpan duration)
10 | {
11 | }
12 |
13 | public void Failed(IRequest request, Exception exception, TimeSpan duration)
14 | {
15 | }
16 |
17 | public void Fallback(IRequest request, TimeSpan duration)
18 | {
19 | }
20 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.2.0] - 2025-01-14
9 |
10 | ### Added
11 | * Added publicOnly parameter to AddDependencyCall method
12 | * Unified DependencyCall registration behavior across different Scrutor versions
13 |
14 | ## [1.1.0] - 2024-01-31
15 |
16 | ### Added
17 |
18 | * Filtered out Microsoft packages from assembly loading due to a bug in Microsoft.Data.SqlClient and .net 8
19 |
20 | ## [1.0.0] - 2023-06-27
21 |
22 | ### Added
23 |
24 | * Initiated Allegro.Extensions.DependencyCall project with DependencyCall abstractions
--------------------------------------------------------------------------------
/src/Allegro.Extensions.DependencyCall/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.2.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Financials/Allegro.Extensions.Financials.Tests.Unit/Allegro.Extensions.Financials.Tests.Unit.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | all
17 | runtime; build; native; contentfiles; analyzers; buildtransitive
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Financials/Allegro.Extensions.Financials.Tests.Unit/Extensions/MoneyExtensionsTests.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Financials.Extensions;
2 | using Allegro.Extensions.Financials.ValueObjects;
3 | using FluentAssertions;
4 | using Xunit;
5 |
6 | namespace Allegro.Extensions.Financials.Tests.Unit.Extensions;
7 |
8 | public class MoneyExtensionsTests
9 | {
10 | [Fact]
11 | public void Sum_Money_Items()
12 | {
13 | var moneys = new List
14 | {
15 | new(10),
16 | new(5),
17 | new(0),
18 | };
19 |
20 | var sum = moneys.Sum();
21 | sum.Should().NotBeNull();
22 | sum.Amount.Should().Be(15);
23 | }
24 |
25 | [Fact]
26 | public void Sum_Money_Items_with_null()
27 | {
28 | var moneys = new List
29 | {
30 | new(5),
31 | new(2),
32 | };
33 |
34 | var sum = moneys.Sum();
35 | sum.Should().NotBeNull();
36 | sum.Amount.Should().Be(7);
37 | }
38 |
39 | [Fact]
40 | public void Sum_Struct_with_money()
41 | {
42 | var moneys = new List
43 | {
44 | new(5.10m),
45 | new(4.20m),
46 | new(-2),
47 | };
48 |
49 | var sum = moneys.Sum(x => x.Money);
50 | sum.Should().NotBeNull();
51 | sum.Amount.Should().Be(7.30m);
52 | }
53 |
54 | [Fact]
55 | public void Sum_Class_with_money()
56 | {
57 | var moneys = new List
58 | {
59 | new(5.10m),
60 | new(4.20m),
61 | new(-2),
62 | };
63 |
64 | var sum = moneys.Sum(x => x.Money);
65 | sum.Should().NotBeNull();
66 | sum.Amount.Should().Be(7.30m);
67 | }
68 |
69 | private readonly struct StructWithMoney
70 | {
71 | public Money Money { get; }
72 |
73 | public StructWithMoney(decimal money)
74 | {
75 | Money = new Money(money);
76 | }
77 | }
78 |
79 | private class ClassWithMoney
80 | {
81 | public Money Money { get; }
82 |
83 | public ClassWithMoney(decimal money)
84 | {
85 | Money = new Money(money);
86 | }
87 | }
88 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Financials/Allegro.Extensions.Financials.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Financials", "Allegro.Extensions.Financials\Allegro.Extensions.Financials.csproj", "{E1C61F6A-FEAA-4252-87DF-C0EBD17AEDF0}"
4 | EndProject
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Financials.Tests.Unit", "Allegro.Extensions.Financials.Tests.Unit\Allegro.Extensions.Financials.Tests.Unit.csproj", "{272A2598-7520-402B-A07D-22C4FE518B82}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|Any CPU = Debug|Any CPU
10 | Release|Any CPU = Release|Any CPU
11 | EndGlobalSection
12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
13 | {E1C61F6A-FEAA-4252-87DF-C0EBD17AEDF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14 | {E1C61F6A-FEAA-4252-87DF-C0EBD17AEDF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
15 | {E1C61F6A-FEAA-4252-87DF-C0EBD17AEDF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
16 | {E1C61F6A-FEAA-4252-87DF-C0EBD17AEDF0}.Release|Any CPU.Build.0 = Release|Any CPU
17 | {272A2598-7520-402B-A07D-22C4FE518B82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18 | {272A2598-7520-402B-A07D-22C4FE518B82}.Debug|Any CPU.Build.0 = Debug|Any CPU
19 | {272A2598-7520-402B-A07D-22C4FE518B82}.Release|Any CPU.ActiveCfg = Release|Any CPU
20 | {272A2598-7520-402B-A07D-22C4FE518B82}.Release|Any CPU.Build.0 = Release|Any CPU
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Financials/Allegro.Extensions.Financials/Allegro.Extensions.Financials.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.Financials
5 | Contains money value object and currency.
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Financials/Allegro.Extensions.Financials/Extensions/MoneyExtensions.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Financials.ValueObjects;
2 |
3 | namespace Allegro.Extensions.Financials.Extensions;
4 |
5 | ///
6 | /// Money related extensions
7 | ///
8 | public static class MoneyExtensions
9 | {
10 | ///
11 | /// Sum money in collection of objects that contains money
12 | ///
13 | public static Money Sum(this IEnumerable source, Func selector)
14 | {
15 | ArgumentNullException.ThrowIfNull(source);
16 | ArgumentNullException.ThrowIfNull(selector);
17 |
18 | var sum = Money.Zero;
19 | return source.Aggregate(sum, (current, item) => current + selector(item));
20 | }
21 |
22 | ///
23 | /// Sum money in collection of money objects
24 | ///
25 | public static Money Sum(this IEnumerable source)
26 | {
27 | ArgumentNullException.ThrowIfNull(source);
28 |
29 | var sum = Money.Zero;
30 | return source.Aggregate(sum, (current, item) => current + item);
31 | }
32 |
33 | ///
34 | /// Allows to round money value with Math.Round api
35 | ///
36 | public static Money? Round(this Money? money, int decimals, MidpointRounding midpointRounding)
37 | {
38 | if (money == null)
39 | {
40 | return null;
41 | }
42 |
43 | return new Money(
44 | Amount: Math.Round(money.Amount, decimals, midpointRounding),
45 | Currency: money.Currency);
46 | }
47 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Financials/Allegro.Extensions.Financials/ValueObjects/Currency.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.Serialization;
2 | #pragma warning disable CS1591
3 |
4 | namespace Allegro.Extensions.Financials.ValueObjects;
5 |
6 | ///
7 | /// Country currency codes (ISO 4217).
8 | /// https://www.iban.com/currency-codes
9 | ///
10 | public enum Currency
11 | {
12 | [EnumMember(Value = "PLN")]
13 | PLN = 985,
14 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Financials/Allegro.Extensions.Financials/ValueObjects/Money.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Financials.ValueObjects;
2 |
3 | ///
4 | /// Value object to store money related data in standardize way
5 | ///
6 | public partial record Money(
7 | decimal Amount,
8 | Currency Currency = Currency.PLN)
9 | {
10 | ///
11 | /// Creates money with value 0 and default currency (PLN)
12 | ///
13 | public static Money Zero => new(0);
14 |
15 | ///
16 | /// Defualt string representation of money
17 | ///
18 | public override string ToString() => $"{Amount} {Currency}";
19 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Financials/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.0.0] - 2022-05-25
9 |
10 | ### Added
11 |
12 | * Initiated Allegro.Extensions.Financials project with money value object.
13 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Financials/README.md:
--------------------------------------------------------------------------------
1 | # Allegro.Extensions.Financials
2 |
3 | Contains money value object and currency.
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Financials/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.0.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Globalization/Allegro.Extensions.Globalization.Tests/Allegro.Extensions.Globalization.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | AnyCPU;x64
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Globalization/Allegro.Extensions.Globalization/Allegro.Extensions.Globalization.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.Globalization
5 | Contains classes that define culture-related information, including language, country/region, calendars in use, format patterns for dates, currency, and numbers, and sort order for strings. These classes are useful for writing globalized (internationalized) applications.
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Globalization/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.0.0] - 2022-05-18
9 |
10 | ### Added
11 |
12 | * Initiated Allegro.Extensions.Globalization project and PolishPluralizer added
13 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Globalization/README.md:
--------------------------------------------------------------------------------
1 | # Allegro.Extensions.Globalization
2 |
3 | Contains classes that define culture-related information, including language, country/region, calendars in use, format patterns for dates, currency, and numbers, and sort order for strings. These classes are useful for writing globalized (internationalized) applications.
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Globalization/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.0.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Abstractions/Allegro.Extensions.Identifiers.Abstractions.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.Identifiers.Abstractions
5 | Contains strongly typed identifiers abstractions.
6 | CS1574
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Abstractions/IStronglyTypedEntity.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Identifiers.Abstractions;
2 |
3 | ///
4 | /// Marker interface for strongly typed entities
5 | ///
6 | public interface IStronglyTypedEntity
7 | where T : IStronglyTypedId
8 | {
9 | ///
10 | /// Strongly typed entity id
11 | ///
12 | public T Id { get; }
13 | }
14 |
15 | ///
16 | /// Marker interface for strongly typed identifiers
17 | ///
18 | public interface IStronglyTypedEntity : IStronglyTypedEntity
19 | where T : IStronglyTypedId
20 | {
21 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Abstractions/IStronglyTypedId.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Identifiers.Abstractions;
2 |
3 | ///
4 | /// Marker interface. Indicates if type should be treated as a strongly typed identifier.
5 | /// Meziantou.Framework.StronglyTypedId that is recommended as a code generator implements this interface by default and provides common JSON serializers.
6 | ///
7 | public interface IStronglyTypedId
8 | {
9 | ///
10 | /// Value of identifier
11 | ///
12 | public T Value { get; }
13 |
14 | ///
15 | /// String value of identifier
16 | ///
17 | public string ValueAsString { get; }
18 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.AspNetCore/Allegro.Extensions.Identifiers.AspNetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.Identifiers.AspNetCore
5 | Contains strongly typed identifiers extensions for swagger.
6 | CS1574
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Demo/Allegro.Extensions.Identifiers.Demo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Demo/Controllers/TestController.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Identifiers.Demo.Identifiers;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace Allegro.Extensions.Identifiers.Demo.Controllers
5 | {
6 | [ApiController]
7 | [Route("strongly-typed")]
8 | public class StronglyTypedExamples : ControllerBase
9 | {
10 | [HttpGet]
11 | public IActionResult Get()
12 | {
13 | return Ok(new { UserId = UserId.Generate(), PaymentId = PaymentId.Parse("123"), OrderId = OrderId.FromGuid(Guid.NewGuid()) });
14 | }
15 |
16 | [HttpPost]
17 | public IActionResult Post([FromQuery] UserId userId, [FromQuery] PaymentId paymentId, [FromQuery] OrderId orderId)
18 | {
19 | return Ok(new { UserId = userId, PaymentId = paymentId, OrderId = orderId });
20 | }
21 |
22 | [HttpGet("{userId}")]
23 | public IActionResult Post([FromRoute] UserId userId)
24 | {
25 | return Ok(new { UserId = userId });
26 | }
27 |
28 | [HttpPost("body")]
29 | public IActionResult Post([FromBody] Dto dto)
30 | {
31 | return Ok(dto);
32 | }
33 |
34 | public record Dto(UserId UserId, PaymentId PaymentId, OrderId OrderId);
35 | }
36 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Demo/Identifiers/OrderId.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) PlaceholderCompany. All rights reserved.
2 | #pragma warning disable 1591
3 |
4 | using Allegro.Extensions.Identifiers.Abstractions;
5 | using Meziantou.Framework.Annotations;
6 |
7 | namespace Allegro.Extensions.Identifiers.Demo.Identifiers;
8 |
9 | [StronglyTypedId(typeof(Guid))]
10 | public partial class OrderId : IStronglyTypedId
11 | {
12 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Demo/Identifiers/PaymentId.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) PlaceholderCompany. All rights reserved.
2 |
3 | using Allegro.Extensions.Identifiers.Abstractions;
4 | using Meziantou.Framework.Annotations;
5 |
6 | namespace Allegro.Extensions.Identifiers.Demo.Identifiers;
7 |
8 | [StronglyTypedId(typeof(int))]
9 | public partial class PaymentId : IStronglyTypedId
10 | {
11 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Demo/Identifiers/UserId.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) PlaceholderCompany. All rights reserved.
2 |
3 | using Allegro.Extensions.Identifiers.Abstractions;
4 | using Meziantou.Framework.Annotations;
5 |
6 | namespace Allegro.Extensions.Identifiers.Demo.Identifiers;
7 |
8 | [StronglyTypedId(typeof(string))]
9 | public partial class UserId : IStronglyTypedId
10 | {
11 | public static UserId Generate() => FromString(Guid.NewGuid().ToString());
12 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Demo/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.Identifiers.Demo
2 | {
3 | public static class Program
4 | {
5 | public static void Main(string[] args)
6 | {
7 | Host.CreateDefaultBuilder(args)
8 | .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup())
9 | .Build()
10 | .Run();
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Demo/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Allegro.Extensions.AspNetCore.Demo": {
4 | "commandName": "Project",
5 | "launchBrowser": true,
6 | "launchUrl": "swagger",
7 | "environmentVariables": {
8 | "ASPNETCORE_ENVIRONMENT": "Development"
9 | },
10 | "applicationUrl": "https://localhost:5001;http://localhost:5000"
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.Demo/Startup.cs:
--------------------------------------------------------------------------------
1 | using Allegro.Extensions.Identifiers.AspNetCore.Swagger;
2 |
3 | namespace Allegro.Extensions.Identifiers.Demo
4 | {
5 | public class Startup
6 | {
7 | private readonly IWebHostEnvironment _env;
8 |
9 | public Startup(IWebHostEnvironment env)
10 | {
11 | _env = env;
12 | }
13 |
14 | public void Configure(IApplicationBuilder app)
15 | {
16 | app
17 | .UseRouting()
18 | .UseSwagger()
19 | .UseSwaggerUI()
20 | .UseEndpoints(endpoints => { endpoints.MapControllers(); });
21 | }
22 |
23 | public void ConfigureServices(IServiceCollection services)
24 | {
25 | services
26 | .AddControllers();
27 |
28 | services
29 | .AddStronglyTypedIds()
30 | .AddSwaggerGen();
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/Allegro.Extensions.Identifiers.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Identifiers.Abstractions", "Allegro.Extensions.Identifiers.Abstractions\Allegro.Extensions.Identifiers.Abstractions.csproj", "{1196D276-39C2-4EA1-966D-6775D17B0DC5}"
4 | EndProject
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Identifiers.AspNetCore", "Allegro.Extensions.Identifiers.AspNetCore\Allegro.Extensions.Identifiers.AspNetCore.csproj", "{964DDB21-8B3A-43B7-A4F3-69A35875EF84}"
6 | EndProject
7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Identifiers.Demo", "Allegro.Extensions.Identifiers.Demo\Allegro.Extensions.Identifiers.Demo.csproj", "{22E35C09-957D-4A5A-8D0C-CA316093DED1}"
8 | EndProject
9 | Global
10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
11 | Debug|Any CPU = Debug|Any CPU
12 | Release|Any CPU = Release|Any CPU
13 | EndGlobalSection
14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
15 | {1196D276-39C2-4EA1-966D-6775D17B0DC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
16 | {1196D276-39C2-4EA1-966D-6775D17B0DC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
17 | {1196D276-39C2-4EA1-966D-6775D17B0DC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
18 | {1196D276-39C2-4EA1-966D-6775D17B0DC5}.Release|Any CPU.Build.0 = Release|Any CPU
19 | {964DDB21-8B3A-43B7-A4F3-69A35875EF84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20 | {964DDB21-8B3A-43B7-A4F3-69A35875EF84}.Debug|Any CPU.Build.0 = Debug|Any CPU
21 | {964DDB21-8B3A-43B7-A4F3-69A35875EF84}.Release|Any CPU.ActiveCfg = Release|Any CPU
22 | {964DDB21-8B3A-43B7-A4F3-69A35875EF84}.Release|Any CPU.Build.0 = Release|Any CPU
23 | {22E35C09-957D-4A5A-8D0C-CA316093DED1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {22E35C09-957D-4A5A-8D0C-CA316093DED1}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {22E35C09-957D-4A5A-8D0C-CA316093DED1}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {22E35C09-957D-4A5A-8D0C-CA316093DED1}.Release|Any CPU.Build.0 = Release|Any CPU
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.3.0] - 2024-01-26
9 | * Updated to version 2.1.0 of Meziantou.Framework.StronglyTypedId and Microsoft.CodeAnalysis to 4.8.0
10 | * Fixed AddStronglyTypedIds failing becouse of https://github.com/dotnet/SqlClient/issues/1930
11 | ### Fix
12 |
13 | * Updated to version 1.0.34 of Meziantou.Framework.StronglyTypedId and Microsoft.CodeAnalysis to 4.7.0
14 |
15 | ## [1.2.0] - 2023-01-03
16 |
17 | ### Fix
18 |
19 | * Update toe 1.0.28 version of Meziantou.Framework.StronglyTypedId with need to install .net sdk v6.0.404 to make it work properly
20 |
21 | ## [1.1.1] - 2023-01-03
22 |
23 | ### Fix
24 |
25 | * Stick to version 1.0.22 of Meziantou.Framework.StronglyTypedId as higher versions introduces some errors: https://github.com/meziantou/Meziantou.Framework/issues/507
26 |
27 | ## [1.1.0] - 2022-11-15
28 |
29 | ### Changed
30 |
31 | * Updated AddStronglyTypedIds to remove assembly naming convention used for Swagger mapping configuration.
32 |
33 | ## [1.0.0] - 2022-05-26
34 |
35 | ### Added
36 |
37 | * Initiated Allegro.Extensions.Identifiers.Abstractions with basic entity and id.
38 |
39 | ## [1.0.0] - 2022-05-26
40 |
41 | ### Added
42 |
43 | * Initiated Allegro.Extensions.Identifiers.AspNetCore with swagger extensions.
44 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Identifiers/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.4.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.NullableReferenceTypes/Allegro.Extensions.NullableReferenceTypes.Tests.Unit/Allegro.Extensions.NullableReferenceTypes.Tests.Unit.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | ${NoWarn},CS8618
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.NullableReferenceTypes/Allegro.Extensions.NullableReferenceTypes.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.NullableReferenceTypes", "Allegro.Extensions.NullableReferenceTypes\Allegro.Extensions.NullableReferenceTypes.csproj", "{FE489585-F1F4-4D01-9EFB-7380CC61EE53}"
4 | EndProject
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.NullableReferenceTypes.Tests.Unit", "Allegro.Extensions.NullableReferenceTypes.Tests.Unit\Allegro.Extensions.NullableReferenceTypes.Tests.Unit.csproj", "{1150B88B-C4B7-4D11-B689-ADB0AD2AACD8}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|Any CPU = Debug|Any CPU
10 | Release|Any CPU = Release|Any CPU
11 | EndGlobalSection
12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
13 | {FE489585-F1F4-4D01-9EFB-7380CC61EE53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14 | {FE489585-F1F4-4D01-9EFB-7380CC61EE53}.Debug|Any CPU.Build.0 = Debug|Any CPU
15 | {FE489585-F1F4-4D01-9EFB-7380CC61EE53}.Release|Any CPU.ActiveCfg = Release|Any CPU
16 | {FE489585-F1F4-4D01-9EFB-7380CC61EE53}.Release|Any CPU.Build.0 = Release|Any CPU
17 | {1150B88B-C4B7-4D11-B689-ADB0AD2AACD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18 | {1150B88B-C4B7-4D11-B689-ADB0AD2AACD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
19 | {1150B88B-C4B7-4D11-B689-ADB0AD2AACD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
20 | {1150B88B-C4B7-4D11-B689-ADB0AD2AACD8}.Release|Any CPU.Build.0 = Release|Any CPU
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.NullableReferenceTypes/Allegro.Extensions.NullableReferenceTypes/Allegro.Extensions.NullableReferenceTypes.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.NullableReferenceTypes
5 | Contains useful classes and extensions for projects which use NRT.
6 | ${NoWarn},CS8618
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.NullableReferenceTypes/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.0.0] - 2022-05-26
9 |
10 | ### Added
11 |
12 | * Initiated Allegro.Extensions.NullableReferenceTypes project with ObjectValidator
13 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.NullableReferenceTypes/README.md:
--------------------------------------------------------------------------------
1 | # Allegro.Extensions.NullableReferenceTypes
2 |
3 | Contains useful classes and extensions for projects which use NRT.
--------------------------------------------------------------------------------
/src/Allegro.Extensions.NullableReferenceTypes/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.0.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.RateLimiting/Allegro.Extensions.RateLimiting.Tests.Unit/Allegro.Extensions.RateLimiting.Tests.Unit.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | all
17 | runtime; build; native; contentfiles; analyzers; buildtransitive
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.RateLimiting/Allegro.Extensions.RateLimiting.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1A5C6678-1714-4D2A-A0B5-DF08B4796E92}"
4 | EndProject
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.RateLimiting", "Allegro.Extensions.RateLimiting\Allegro.Extensions.RateLimiting.csproj", "{2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}"
6 | EndProject
7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.RateLimiting.Tests.Unit", "Allegro.Extensions.RateLimiting.Tests.Unit\Allegro.Extensions.RateLimiting.Tests.Unit.csproj", "{FAC8446F-E898-4265-84FC-291AC35F6195}"
8 | EndProject
9 | Global
10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
11 | Debug|Any CPU = Debug|Any CPU
12 | Release|Any CPU = Release|Any CPU
13 | EndGlobalSection
14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
15 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
16 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Debug|Any CPU.Build.0 = Debug|Any CPU
17 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Release|Any CPU.ActiveCfg = Release|Any CPU
18 | {2E3FAF13-980B-40D2-9FFC-8D9CDB06F641}.Release|Any CPU.Build.0 = Release|Any CPU
19 | {FAC8446F-E898-4265-84FC-291AC35F6195}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20 | {FAC8446F-E898-4265-84FC-291AC35F6195}.Debug|Any CPU.Build.0 = Debug|Any CPU
21 | {FAC8446F-E898-4265-84FC-291AC35F6195}.Release|Any CPU.ActiveCfg = Release|Any CPU
22 | {FAC8446F-E898-4265-84FC-291AC35F6195}.Release|Any CPU.Build.0 = Release|Any CPU
23 | EndGlobalSection
24 | EndGlobal
25 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.RateLimiting/Allegro.Extensions.RateLimiting/Allegro.Extensions.RateLimiting.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.RateLimiting
5 | ...
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.RateLimiting/Allegro.Extensions.RateLimiting/Events/AvgRateCalculated.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.RateLimiting.Events
2 | {
3 | ///
4 | /// Event handler delegate for the event of periodic average rate of rate limiter being calculated.
5 | ///
6 | #pragma warning disable CA1711
7 | public delegate void AvgRateCalculatedEventHandler(object sender, AvgRateCalculatedEventArgs e);
8 | #pragma warning restore CA1711
9 |
10 | ///
11 | /// Event arguments for the event of periodic average rate of rate limiter being calculated.
12 | ///
13 | public class AvgRateCalculatedEventArgs : EventArgs
14 | {
15 | internal AvgRateCalculatedEventArgs(
16 | double avgRate,
17 | TimeSpan period)
18 | {
19 | AvgRate = avgRate;
20 | Period = period;
21 | }
22 |
23 | ///
24 | /// Gets the average rate calculated over given Period.
25 | ///
26 | public double AvgRate { get; }
27 |
28 | ///
29 | /// Gets the period during which the average rate was calculated.
30 | ///
31 | public TimeSpan Period { get; }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.RateLimiting/Allegro.Extensions.RateLimiting/Events/MaxRateChanged.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.RateLimiting.Events
2 | {
3 | ///
4 | /// Event handler delegate for the event of max rate of rate limiter being changed.
5 | ///
6 | #pragma warning disable CA1711
7 | public delegate void MaxRateChangedEventHandler(object sender, MaxRateChangedEventArgs e);
8 | #pragma warning restore CA1711
9 |
10 | ///
11 | /// Event arguments for the event of max rate of rate limiter being changed.
12 | ///
13 | public class MaxRateChangedEventArgs : EventArgs
14 | {
15 | internal MaxRateChangedEventArgs(
16 | double newMaxRate,
17 | double previousMaxRate)
18 | {
19 | NewMaxRate = newMaxRate;
20 | PreviousMaxRate = previousMaxRate;
21 | }
22 |
23 | ///
24 | /// Gets the new max rate that has been set.
25 | ///
26 | public double NewMaxRate { get; }
27 |
28 | ///
29 | /// Gets the previous max rate of the rate limiter.
30 | ///
31 | public double PreviousMaxRate { get; }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.RateLimiting/Allegro.Extensions.RateLimiting/Events/MaxRateExceeded.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.RateLimiting.Events
2 | {
3 | ///
4 | /// Event handler delegate for the event of max rate of rate limiter being exceeded.
5 | ///
6 | #pragma warning disable CA1711
7 | public delegate void MaxRateExceededEventHandler(object sender, MaxRateExceededEventArgs e);
8 | #pragma warning restore CA1711
9 |
10 | ///
11 | /// Event arguments for the event of max rate of rate limiter being exceeded.
12 | ///
13 | public class MaxRateExceededEventArgs : EventArgs
14 | {
15 | internal MaxRateExceededEventArgs(
16 | double maxRate,
17 | double accumulatedOps,
18 | double attemptedOpWeight,
19 | double delayMilliseconds)
20 | {
21 | MaxRate = maxRate;
22 | AccumulatedOps = accumulatedOps;
23 | AttemptedOpWeight = attemptedOpWeight;
24 | DelayMilliseconds = delayMilliseconds;
25 | }
26 |
27 | ///
28 | /// Gets the maximum rate of the rate limiter.
29 | ///
30 | public double MaxRate { get; }
31 |
32 | ///
33 | /// Gets the total weight of operations executed so far.
34 | ///
35 | public double AccumulatedOps { get; }
36 |
37 | ///
38 | /// Gets the weight of the attempted operation, which exceeded the max rate.
39 | ///
40 | public double AttemptedOpWeight { get; }
41 |
42 | ///
43 | /// Gets the delay in milliseconds that the rate limiter will wait before executing next operations.
44 | ///
45 | public double DelayMilliseconds { get; }
46 | }
47 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.RateLimiting/Allegro.Extensions.RateLimiting/IRateLimiter.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.RateLimiting
2 | {
3 | ///
4 | /// Allows to execute operations with rate limiting
5 | ///
6 | public interface IRateLimiter
7 | {
8 | ///
9 | /// Executes operation with rate limiting.
10 | /// This method is equivalent of ExecuteWeighted with weight = 1.
11 | ///
12 | Task ExecuteAsync(Func> operation) => ExecuteWeightedAsync(operation, 1);
13 |
14 | ///
15 | /// Executes operation with rate limiting.
16 | /// This method is equivalent of ExecuteWeighted with weight = 1.
17 | ///
18 | Task ExecuteAsync(Func operation) => ExecuteWeightedAsync(operation, 1);
19 |
20 | ///
21 | /// Executes operation with rate limiting, given the operation weight.
22 | /// Consumes "weight" from the defined limit.
23 | ///
24 | Task ExecuteWeightedAsync(Func> operation, double weight);
25 |
26 | ///
27 | /// Executes operation with rate limiting, given the operation weight.
28 | /// Consumes "weight" from the defined limit.
29 | ///
30 | Task ExecuteWeightedAsync(Func operation, double weight);
31 |
32 | ///
33 | /// Executes operation with rate limiting, estimating its weight based on previous executions of similar operation.
34 | ///
35 | /// Name of the operation (it will be used to estimate weight based on previous executions)
36 | /// Operation to execute
37 | /// Callback function to calculate (post-factum) the weight of the executed operation.
38 | Task ExecuteWithEstimatedWeightAsync(
39 | string operationName,
40 | Func> operation,
41 | Func weightCalculator);
42 | }
43 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.RateLimiting/Allegro.Extensions.RateLimiting/IRateLimiterWithVariableRate.cs:
--------------------------------------------------------------------------------
1 | namespace Allegro.Extensions.RateLimiting
2 | {
3 | ///
4 | /// Allows to execute operations with rate limiting and change the rate dynamically.
5 | ///
6 | public interface IRateLimiterWithVariableRate : IRateLimiter
7 | {
8 | ///
9 | /// Gets the calculated average rate metric value.
10 | ///
11 | double AvgRate { get; }
12 |
13 | ///
14 | /// Gets the max rate of the rate limiter.
15 | ///
16 | double MaxRate { get; }
17 |
18 | ///
19 | /// Gets the interval over which the rate is limited.
20 | ///
21 | TimeSpan RateInterval { get; }
22 |
23 | ///
24 | /// Changes the max rate.
25 | ///
26 | /// New max rate to be set
27 | void ChangeMaxRate(double maxRate);
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.RateLimiting/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.2.0] - 2022-05-06
9 |
10 | ### Removed
11 |
12 | * Removed targeting net5.0
13 |
14 | ## [1.1.0] - 2022-03-28
15 |
16 | ### Changed
17 |
18 | * Multitargeting net5.0;net6.0
19 |
20 | ## [1.0.1] - 2022-03-15
21 |
22 | ### Changed
23 |
24 | * Minor code & tests refactor
25 |
26 | ## [1.0.0] - 2022-03-10
27 |
28 | ### Added
29 |
30 | * Initiated Allegro.Extensions.RateLimiting project
31 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.RateLimiting/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.2.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Serialization/Allegro.Extensions.Serialization.Tests.Unit/Allegro.Extensions.Serialization.Tests.Unit.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | AnyCPU;x64
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Serialization/Allegro.Extensions.Serialization.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Serialization", "Allegro.Extensions.Serialization\Allegro.Extensions.Serialization.csproj", "{67F2FA4E-EA48-4C88-A5D9-0186741456A4}"
4 | EndProject
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Serialization.Tests.Unit", "Allegro.Extensions.Serialization.Tests.Unit\Allegro.Extensions.Serialization.Tests.Unit.csproj", "{80E83F63-43D4-406F-BDC5-AFD49213E8C1}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|Any CPU = Debug|Any CPU
10 | Release|Any CPU = Release|Any CPU
11 | EndGlobalSection
12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
13 | {67F2FA4E-EA48-4C88-A5D9-0186741456A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14 | {67F2FA4E-EA48-4C88-A5D9-0186741456A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
15 | {67F2FA4E-EA48-4C88-A5D9-0186741456A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
16 | {67F2FA4E-EA48-4C88-A5D9-0186741456A4}.Release|Any CPU.Build.0 = Release|Any CPU
17 | {80E83F63-43D4-406F-BDC5-AFD49213E8C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18 | {80E83F63-43D4-406F-BDC5-AFD49213E8C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
19 | {80E83F63-43D4-406F-BDC5-AFD49213E8C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
20 | {80E83F63-43D4-406F-BDC5-AFD49213E8C1}.Release|Any CPU.Build.0 = Release|Any CPU
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Serialization/Allegro.Extensions.Serialization/Allegro.Extensions.Serialization.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.Serialization
5 | Contains serialization extensions and enum member helpers.
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Serialization/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.0.0] - 2022-05-18
9 |
10 | ### Added
11 |
12 | * Initiated Allegro.Extensions.Serialization project with EnumMember extension.
13 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Serialization/README.md:
--------------------------------------------------------------------------------
1 | # Allegro.Extensions.Serialization
2 |
3 | Contains serialization extensions and enum member helpers.
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Serialization/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.0.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Validators/Allegro.Extensions.Validators.Tests.Unit/Allegro.Extensions.Validators.Tests.Unit.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | ${NoWarn},CS8618
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Validators/Allegro.Extensions.Validators.Tests.Unit/InputValidatorTests.cs:
--------------------------------------------------------------------------------
1 | using FluentAssertions;
2 | using Xunit;
3 |
4 | namespace Allegro.Extensions.Validators.Tests.Unit;
5 |
6 | public class InputValidatorTests
7 | {
8 | [Theory]
9 | [InlineData(null)]
10 | [InlineData("")]
11 | [InlineData(" ")]
12 | public void EnsureHasValue_WhenInvalidInput_ShouldThrowArgumentNullException(string test)
13 | {
14 | var act = () => InputValidator.EnsureHasValue(test);
15 | act.Should().Throw();
16 | }
17 |
18 | [Theory]
19 | [InlineData("testowy_string")]
20 | [InlineData("12333333")]
21 | public void EnsureHasValue_WhenValidInput_ShouldNotThrowAnyException(string value)
22 | {
23 | var act = () => InputValidator.EnsureHasValue(value);
24 | act.Should().NotThrow();
25 | }
26 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Validators/Allegro.Extensions.Validators.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Validators", "Allegro.Extensions.Validators\Allegro.Extensions.Validators.csproj", "{FE489585-F1F4-4D01-9EFB-7380CC61EE53}"
4 | EndProject
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Allegro.Extensions.Validators.Tests.Unit", "Allegro.Extensions.Validators.Tests.Unit\Allegro.Extensions.Validators.Tests.Unit.csproj", "{1150B88B-C4B7-4D11-B689-ADB0AD2AACD8}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|Any CPU = Debug|Any CPU
10 | Release|Any CPU = Release|Any CPU
11 | EndGlobalSection
12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
13 | {FE489585-F1F4-4D01-9EFB-7380CC61EE53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14 | {FE489585-F1F4-4D01-9EFB-7380CC61EE53}.Debug|Any CPU.Build.0 = Debug|Any CPU
15 | {FE489585-F1F4-4D01-9EFB-7380CC61EE53}.Release|Any CPU.ActiveCfg = Release|Any CPU
16 | {FE489585-F1F4-4D01-9EFB-7380CC61EE53}.Release|Any CPU.Build.0 = Release|Any CPU
17 | {1150B88B-C4B7-4D11-B689-ADB0AD2AACD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18 | {1150B88B-C4B7-4D11-B689-ADB0AD2AACD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
19 | {1150B88B-C4B7-4D11-B689-ADB0AD2AACD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
20 | {1150B88B-C4B7-4D11-B689-ADB0AD2AACD8}.Release|Any CPU.Build.0 = Release|Any CPU
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Validators/Allegro.Extensions.Validators/Allegro.Extensions.Validators.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Allegro.Extensions.Validators
5 | Contains useful classes and extensions validators.
6 | ${NoWarn},CS8618,SA1636
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Validators/Allegro.Extensions.Validators/OptionsBuilderFluentValidationExtensions.cs:
--------------------------------------------------------------------------------
1 | /* The MIT License (MIT)
2 |
3 | Copyright (c) 2016 andrewlock
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 | using Microsoft.Extensions.DependencyInjection;
23 | using Microsoft.Extensions.Options;
24 |
25 | namespace Allegro.Extensions.Validators;
26 |
27 | ///
28 | /// Fluent validation extensions for options builder
29 | ///
30 | public static class OptionsBuilderFluentValidationExtensions
31 | {
32 | ///
33 | /// Adds a IValidateOptions<TOptions> service with fluent validation.
34 | ///
35 | public static OptionsBuilder ValidateFluentValidation(
36 | this OptionsBuilder optionsBuilder) where TOptions : class
37 | {
38 | optionsBuilder.Services.AddSingleton>(
39 | provider => new FluentValidationOptions(
40 | optionsBuilder.Name, provider));
41 | return optionsBuilder;
42 | }
43 | }
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Validators/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.1.0] - 2022-11-16
9 |
10 | ### Added
11 |
12 | * Fluent validation extensions
13 |
14 | ## [1.0.0] - 2022-07-26
15 |
16 | ### Added
17 |
18 | * Initiated Allegro.Extensions.Validators project with InputValidators
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Validators/README.md:
--------------------------------------------------------------------------------
1 | # Allegro.Extensions.Validators
2 |
3 | Contains useful classes and extensions validators especially null and non empty checks.
4 |
5 | ## Fluent validation
6 |
7 | This package provides extensions for easy registration of fluent validators.
8 |
9 | ### Usage
10 |
11 | Create IOptions with fluent validation enabled
12 |
13 | ```csharp
14 | public void ConfigureServices(IServiceCollection services)
15 | {
16 | services.AddOptionsWithFluentValidation("configuration section name");
17 | }
18 | ```
19 |
20 | Add a fluent validator to IOptionsBuilder
21 |
22 | ```csharp
23 | public void ConfigureServices(IServiceCollection services)
24 | {
25 | services.AddOptions()
26 | .BindConfiguration(configurationSection)
27 | .ValidateFluentValidation();
28 | }
29 | ```
30 |
--------------------------------------------------------------------------------
/src/Allegro.Extensions.Validators/version.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.2.0
4 |
5 |
--------------------------------------------------------------------------------
/src/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(NetCoreVersions)
5 | false
6 |
7 |
8 |
9 | true
10 |
11 |
12 | $(SolutionDir)\bin\$(MSBuildProjectName)
13 | $(SolutionDir)\obj\$(MSBuildProjectName)
14 | $(SolutionDir)\nuget
15 |
16 |
--------------------------------------------------------------------------------
/src/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/Package.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(NetCoreVersions)
5 | Allegro
6 | Allegro
7 | Copyright © Allegro Group
8 | Apache-2.0
9 | https://github.com/allegro/dotnet-utils
10 | README.md
11 | true
12 | snupkg
13 | true
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------