2026-07-14 21:53:48 +02:00
2021-06-15 10:59:47 +02:00

GerstITS Framework Examples

This solution demonstrates all features of the GerstITS framework packages in a small, coherent customer management domain.

Solution layout

Project Purpose
GerstITS.Examples.Api ASP.NET Core Web API host: fluent controllers, minimal API endpoints, versioning, exception handling, Swagger, authentication, session cache, jobs and auto migration.
GerstITS.Examples.Logic Business logic: providers, search engine integration, validation rules, customizations and AutoMapper profiles.
GerstITS.Examples.Data Data access: entities with framework aspects, EF Core DbContext, entity mappings, database configurator and migrations.
GerstITS.Examples.Jobs.SayHelloWorld Scheduled Quartz jobs with cron configuration.
GerstITS.WebClients.Example.Api Typed REST client contract for the example API (ICustomer).
GerstITS.Examples.WebClient.Console Console client consuming the API via IWebClient plus demos of the common/system utilities.
GerstITS.Examples.Tests xUnit tests using the GerstITS test framework categories.

Feature matrix

GerstITS.Common

Feature Example
String/object/enum/enumerable extensions WebClient.Console/Tests/CommonFeaturesRunner.cs
Fluent exception handling (Is(...).ThenThrows<...>().WithMessage(...)) CommonFeaturesRunner.cs, Logic/Customers/CustomerProvider.cs (Import)
Range<T> + Intersects CommonFeaturesRunner.cs
AES cryptography extensions (Encrypt/Decrypt) CommonFeaturesRunner.cs
ApplicationEnvironment detection Api/Program.cs (IsEfCoreActionStarted)

GerstITS.System

Feature Example
ISystemClock MaintenanceController.Ping, SayHelloWorldJob
IJsonConvert Api/Common/StartupTasks/ExampleStartupTask.cs, CommonFeaturesRunner.cs
IActivator CommonFeaturesRunner.cs
ICache (encrypted, session backed) Api/Controllers/1.1/CacheController.cs
Customizations (CustomizationBase<T>, ApplyCustomizations()) Logic/Customers/Customizations/CustomerDisplayNameCustomization.cs
Configuration prefix pattern (ToConfigurationPrefix) Api/Common/Configurations/WebApiConfiguration.*.cs

GerstITS.IoC / GerstITS.IoC.DotNetCore

Feature Example
IIoCModule<IServiceCollection> modules (partial pattern) Module.cs in every project
DotNetCoreApplicationBootstrapper + IApplicationStart WebClient.Console/Program.cs, Tests/TestRunner.cs, Tests/CommonFeaturesRunner.cs
IStartupTask with priorities Api/Common/StartupTasks/ExampleStartupTask.cs
Namespace based assembly scanning (Register...Of<T>()) Logic/Module.Customers.cs

GerstITS.Data / GerstITS.Data.EntityFramework / GerstITS.Data.EntityFramework.PostgreSql

Feature Example
EntityBase<TKey> + aspects (IActivatable, ICreatable, IModifiable, IVersionable) Data/Entities/CustomerEntity.cs
Historization (IHistoricizable) Data/Entities/CustomerNoteEntity.cs
EntityMappingBase<TEntity> Data/Mappings/*.cs
EntityFrameworkDbContextBase + IDbContext Data/CustomerDbContext.cs
PostgreSqlDatabaseConfiguratorBase<TDbContext> Data/Migrations/CustomerDatabaseConfigurator.cs
Design time factory + migrations Data/Migrations/DesignTime/CustomerDbContextDesignTimeFactory.cs, Data/Migrations/20260703*_InitialCreate.cs
Registration (AddMigration, AddEntityFrameworkSession) Data/Module.cs
Repository queries (active only by default, includeInactive opt-in) Logic/Customers/CustomerProvider.cs (GetById)
Soft delete by default, forceDelete opt-in CustomerProvider.Delete
Bulk operations (BulkSave) CustomerProvider.Import
Query projection (Project) Logic/Customers/Search/CustomerSearchQueryBuilderRule.cs
ThrowsAnExceptionIfNotExisting / EntityNotFoundException CustomerProvider.cs, Api/.../EntityNotFoundExceptionTransformation.cs
Auto migration on startup (WebApi:EntityFrameworkMigration:AutoMigrate) Api/appsettings.json

GerstITS.Data.EntityFramework.SqlServer works exactly like the PostgreSql package: derive from SqlServerDatabaseConfiguratorBase<TDbContext> instead. Note that only one IDatabaseConfigurator implementation is allowed per assembly.

GerstITS.Search

Feature Example
ISearchEngine + SearchResult<T> Logic/Customers/CustomerProvider.cs (Search)
SearchFilterBase (paging + sorting) Logic/Customers/Contracts/CustomerSearchFilter.cs
SearchQueryBuilderRuleBase<TItem, TFilter> Logic/Customers/Search/CustomerSearchQueryBuilderRule.cs
InitializationRuleBase<T> (filter defaults) Logic/Customers/Search/CustomerSearchFilterInitializationRule.cs
PagingValidationRuleBase<T> Logic/Customers/Validation/CustomerSearchFilterValidationRule.cs
Custom ISortingProvider Logic/Shared/Search/Sorting/SortingProvider.cs

GerstITS.Validation

Feature Example
ValidationRuleBase<T> (FluentValidation) Logic/Customers/Validation/CustomerValidationRule.cs, Logic/Shared/Validation/IdValidationRule.cs
IsEMail() rule builder extension CustomerValidationRule.cs
Automatic validation in fluent controllers (IValidator) All controllers via FluentApiControllerBase
Explicit validation in minimal API endpoints (IValidator + ToErrorMessage) Api/Endpoints/Endpoints.Validator.cs

GerstITS.Mapping.AutoMapper

Feature Example
Profiles + RegisterMappingsOf<T>() Logic/Customers/Mappings/CustomerMapping.cs, Logic/Example/Mappings/IntegerMapping.cs

GerstITS.Web / GerstITS.Web.Api / GerstITS.Web.Api.Swagger / GerstITS.Web.Rest

Feature Example
HostingStartup fluent pipeline Api/Program.cs
FluentApiControllerBase (Api().Use(...).Get/Create/Update/Delete) Api/Controllers/1.1/*.cs
API versioning (side by side controllers) Api/Controllers/1.0 vs Api/Controllers/1.1
Minimal API endpoints (partial Endpoints class per feature, nested static endpoint classes) Api/Endpoints/Endpoints.cs, Endpoints.Customers.cs, Endpoints.CustomerNotes.cs
Endpoint grouping + Swagger tags (MapGroup, WithTags) Api/Endpoints/Endpoints.Customers.cs
Query parameter binding to search filters ([AsParameters]) Endpoints.Customers.MapSearch
Global exception transformations Api/Common/ExceptionHandling/Transformations/*.cs
Global exception handling middleware for minimal APIs (UseGlobalExceptionHandling) Api/Common/ExceptionHandling/Extensions/WebApplicationExtensions.cs, Api/Program.cs
Automatic response compression (zstd, brotli, gzip — also for HTTPS) built in, no app code required — see "Response compression" below
Server configuration (CORS, HSTS, forwarded headers) Api/Common/Configurations/WebApiConfiguration.Server.*.cs
Swagger configuration incl. security schemes Api/Common/Configurations/WebApiConfiguration.Swagger*.cs, WebApiConfiguration.OpenApiSecurityScheme.cs
Session based cache storage (AddHttpSession) Api/Module.Session.cs, CacheController.cs
Typed REST clients (IWebService, WebMethod, ResourceUrl, HttpHeader) GerstITS.WebClients.Example.Api/Contracts/ICustomer.cs
RestWebServiceConfigurationBase + creation rules GerstITS.WebClients.Example.Api/Configurations, CreationRules
IWebClient.Request<T>().Execute(...) WebClient.Console/Tests/TestRunner.cs

GerstITS.Authentication.ApiKey / GerstITS.Authentication.OpenId

Feature Example
[ApiKey] attribute + IApiKeyConfiguration Api/Controllers/1.1/MaintenanceController.cs, WebApiConfiguration.ApiKey.cs
JWT bearer via IOpenIdConfiguration + [Authorize] Api/Controllers/1.1/SecuredController.cs, WebApiConfiguration.OpenId*.cs

GerstITS.Mail

Feature Example
IMailProvider, MailNotification, ContactRequest Api/Controllers/1.1/ContactController.cs
SMTP configuration (Mail section) Api/appsettings.json

GerstITS.Job / GerstITS.Job.Scheduling

Feature Example
JobBase + cron scheduling Jobs.SayHelloWorld/Jobs/*.cs
JobSchedulingConfigurationBase (named + convention based) Jobs.SayHelloWorld/Configurations/*.cs, Api/appsettings.json (Jobs section)
RegisterJob<TJob, TConfig>() + IgnoreConditions Jobs.SayHelloWorld/Module.cs

GerstITS.TestFramework

Feature Example
[TestCategory(TestCategories.Unit/Integration)] traits GerstITS.Examples.Tests/**/*Test.cs
Filtering: dotnet test --filter "Category=Unit" see below

Running

  1. Database: the API auto-migrates on startup (AutoMigrate: true). Adjust the CustomerDbContext connection string in GerstITS.Examples.Api/appsettings.json (PostgreSQL).
  2. API: start GerstITS.Examples.Api. Swagger UI is available in development at /api/swagger.
  3. Console client: start GerstITS.Examples.WebClient.Console while the API is running.
  4. Tests: dotnet test (optionally --filter "Category=Unit").
  5. Migrations: dotnet ef migrations add <Name> inside GerstITS.Examples.Data (uses the design time factory and appsettings.json of that project).

Fluent controllers vs. minimal API endpoints

The customer domain is exposed twice to compare both styles:

  • POST/GET/PUT/DELETE /api/Customer — fluent controllers (FluentApiControllerBase, validation and exception transformations applied by the fluent pipeline).
  • GET/POST/PUT/DELETE /api/v2.0/customers — minimal API endpoints (partial Endpoints class, explicit Endpoints.Validator, exception transformations applied by UseGlobalExceptionHandling).

Search differs on purpose: the controller uses POST /api/Customer/Search with a body filter, the minimal API uses GET /api/v2.0/customers binding the same CustomerSearchFilter from query parameters via [AsParameters].

Response compression

GerstITS.Web.Api enables response compression automatically — there is nothing to register or configure in the application: the framework module registers the zstd (ZstdSharp), brotli and gzip providers with EnableForHttps = true and HostingStartup...Build() adds the UseResponseCompression() middleware. The provider is picked by the client's Accept-Encoding header (zstd preferred, then brotli, then gzip):

curl -s -D - -o NUL -H "Accept-Encoding: zstd, br, gzip" https://localhost:<port>/api/v2.0/customers

The response then carries the matching Content-Encoding header (e.g. Content-Encoding: zstd).

Requires the first GerstITS.Web.Api release after 2026.7.7 — older packages do not contain the compression feature yet, requests are then answered uncompressed.

Api key protected endpoints

GET /api/Maintenance/Ping requires the header configured under WebApi:ApiKey (default: X-Api-Key: example-api-key).

S
Description
Provides examples how to use framework
Readme
206 KiB
Languages
C# 100%