FokySdk 1.11.6
dotnet add package FokySdk --version 1.11.6
NuGet\Install-Package FokySdk -Version 1.11.6
<PackageReference Include="FokySdk" Version="1.11.6" />
<PackageVersion Include="FokySdk" Version="1.11.6" />
<PackageReference Include="FokySdk" />
paket add FokySdk --version 1.11.6
#r "nuget: FokySdk, 1.11.6"
#:package FokySdk@1.11.6
#addin nuget:?package=FokySdk&version=1.11.6
#tool nuget:?package=FokySdk&version=1.11.6
🚀 FokySdk
🧰 Infrastructure SDK for .NET 10 microservices — common integrations and conventions in one reusable package.
✨ FokySdk is an infrastructure SDK for .NET 10 microservices. It provides reusable integrations and conventions for:
- Swagger / OpenAPI
- JWT authorization support in Swagger UI
- PostgreSQL / Entity Framework Core
- RabbitMQ / MassTransit
- OpenTelemetry
- NLog-based logging
- ASP.NET Core middleware
- Controller response mapping
- Newtonsoft.Json controller configuration
- Service version headers
The package is designed to keep common infrastructure configuration out of individual microservice projects.
📋 Requirements
- .NET 10
- ASP.NET Core 10
📦 Installation
Install the NuGet package:
dotnet add package FokySdk
FokySdk depends on FokySdk.Types, which contains shared DTOs and
configuration types used by the SDK.
📚 Swagger
Namespace:
using FokySdk.Swagger;
using FokySdk.Types.Settings;
🛠️ Register Swagger
builder.Services.AddSwagger(new SwaggerSettings
{
ServiceName = "UsersService",
ServiceVersion = "v1"
});
Then add Swagger middleware:
app.AddSwagger(new SwaggerSettings
{
ServiceName = "UsersService",
ServiceVersion = "v1"
});
This registers the Swagger document and Swagger UI.
🌱 Read service information from environment variables
SwaggerSettings.GetFromEnvironment() reads:
Variable Default Description
SERVICE_NAME SERVICE Swagger service title
SERVICE_VERSION DEV Swagger document version
Example:
var swaggerSettings = SwaggerSettings.GetFromEnvironment();
builder.Services.AddSwagger(swaggerSettings);
// ...
app.AddSwagger(swaggerSettings);
🔐 JWT support in Swagger
JWT support can be enabled with:
var swaggerSettings = SwaggerSettings.GetFromEnvironment()
.WithJwtAuthEnabled();
builder.Services.AddSwagger(swaggerSettings);
// ...
app.AddSwagger(swaggerSettings);
Or explicitly:
builder.Services.AddSwagger(new SwaggerSettings
{
ServiceName = "UsersService",
ServiceVersion = "v1",
JwtAuthEnabled = true
});
When enabled, Swagger UI exposes a Bearer JWT authorization scheme and adds the corresponding security requirement to the OpenAPI document.
This enables the Authorize button in Swagger UI and allows authenticated requests to send:
Authorization: Bearer <jwt-token>
JwtAuthEnabledconfigures JWT support in the Swagger/OpenAPI documentation. It does not configure ASP.NET Core JWT authentication itself. Actual JWT validation must still be configured by the application.
🗄️ Entity Framework Core
Namespace:
using FokySdk.DataAccess;
using FokySdk.Types.Settings;
🔌 Register DbContext
builder.Services.AddEfDbContext<MyDbContext>(
EfCoreConnectionSettings.GetFromEnvironment());
The SDK configures the context to use PostgreSQL through Npgsql.
🌱 Environment variables
EfCoreConnectionSettings.GetFromEnvironment() reads:
Variable Required Description
PG_HOST Yes PostgreSQL host
PG_PORT Yes PostgreSQL port
PG_USER Yes PostgreSQL username
PG_PASSWORD Yes PostgreSQL password
PG_DATABASE Yes Database name
PG_SCHEMA No PostgreSQL schema; defaults to public
The generated connection string also enables detailed PostgreSQL errors and sets the configured search path.
🐇 RabbitMQ
Namespace:
using FokySdk.DataAccess;
using FokySdk.Types.DataAccess;
using FokySdk.Types.Settings;
RabbitMQ integration is built on top of MassTransit.
🔌 Connection settings
var rabbitSettings = RabbitMqSettings.GetFromEnvironment();
Environment variables:
Variable Required Default
RABBIT_MQ_HOST Yes ---
RABBIT_MQ_PORT Yes ---
RABBIT_MQ_USER Yes ---
RABBIT_MQ_PASSWORD Yes ---
RABBIT_MQ_VHOST No /
🛠️ Register RabbitMQ
builder.Services.AddRabbitMq(
rabbitSettings,
consumersRegister: x =>
{
x.AddConsumer<UserCreatedConsumer>();
},
consumersAdd: (cfg, context) =>
{
RabbitMq.AddConsumer<UserCreatedConsumer>(
cfg,
context,
new RabbitMqConsumer
{
Queue = "users-service",
Exchange = "users",
RoutingKey = "user.created",
ExchangeType = ExchangeType.Topic
});
},
publishersRegister: cfg =>
{
RabbitMq.AddPublisher<UserCreated>(
cfg,
new RabbitMqPublisher("users"));
});
All consumer/publisher registration callbacks are optional and can be
null.
📥 Consumer
RabbitMqConsumer describes a consumer endpoint:
new RabbitMqConsumer
{
Queue = "users-service",
Exchange = "users",
RoutingKey = "user.created",
ExchangeType = ExchangeType.Topic
}
The SDK creates a receive endpoint, disables MassTransit's automatic consume topology, binds the specified exchange, and configures the consumer.
🔄 Retry
A consumer can optionally use a retry policy:
RabbitMq.AddConsumer<UserCreatedConsumer>(
cfg,
context,
consumer,
new RabbitMqRetrySettings
{
RetryCount = 3,
Interval = TimeSpan.FromSeconds(5)
});
This configures an interval retry policy.
📤 Publisher
Publishers can be configured with:
new RabbitMqPublisher(
exchange: "users",
exchangeType: ExchangeType.Topic,
durable: true);
Then:
RabbitMq.AddPublisher<UserCreated>(cfg, publisher);
The SDK configures the MassTransit message entity name, durability, and exchange type.
Currently supported exchange type:
ExchangeType.Topic
📈 OpenTelemetry
Namespace:
using FokySdk.Telemetry;
using FokySdk.Types.Settings;
🛠️ Register OpenTelemetry
var serviceInfo = OtelServiceInfo.GetFromEnvironment();
builder.Services.AddOtelServices(
serviceInfo,
new OtelSettings
{
UseAspNetCoreInstrumentation = true,
UseHttpClientInstrumentation = true,
UseEntityFrameworkInstrumentation = true,
UseMassTransitInstrumentation = true
});
The SDK configures:
- OpenTelemetry tracing
- ASP.NET Core instrumentation
- HttpClient instrumentation
- Entity Framework Core instrumentation
- MassTransit instrumentation
- OTLP/gRPC exporting
- W3C Trace Context propagation
- Baggage propagation
Each instrumentation type can be enabled independently.
🌱 Environment variables
OtelServiceInfo.GetFromEnvironment() reads:
Variable Required Description
OTEL_SERVICE_NAME Yes Service name
OTEL_GRPC_ENDPOINT Yes OTLP gRPC exporter endpoint
Example:
OTEL_SERVICE_NAME=users-service
OTEL_GRPC_ENDPOINT=http://jaeger-collector:4317
🧩 Custom ActivitySource
The SDK exposes a shared ActivitySource:
using FokySdk.Telemetry;
var activitySource = OpenTelemetry.Providers.TraceSource;
It is registered in dependency injection as a singleton.
You can create custom spans using the registered ActivitySource.
📝 Logging
Namespace:
using FokySdk.Logging;
using FokySdk.Types.Settings;
The SDK provides an ILogger abstraction backed by NLog.
⚙️ Configure logger
var settings = new LoggerSettings
{
UseConsoleTarget = true,
UseFileTarget = true,
FileName = "app.log",
MinLevel = NLog.LogLevel.Info,
MaxLevel = NLog.LogLevel.Fatal
};
var logger = new Logger(settings);
LoggerSettings supports:
Property Default Description
ConsoleLayout ${time} ${level} ${message} Console log layout
FileLayout ${longdate} ${level} ${message} ${exception} File log layout
FileName app.log File target name/path
UseConsoleTarget true Enable console target
ConsoleTargetName console Console target name
UseFileTarget true Enable file target
FileTargetName file File target name
MinLevel Info Minimum log level
MaxLevel Fatal Maximum log level
ExcludedStrings --- Strings to mask in
messages
Sensitive strings can be masked before the message is written:
new LoggerSettings
{
ExcludedStrings = new List<string>
{
"secret-password",
"sensitive-token"
}
};
The logger replaces each excluded string with *.
🪵 ILogger
public interface ILogger
{
void LogInfo(string message);
void LogWarning(string message);
void LogError(string message);
}
🎯 Controller response mapping
Namespace:
using FokySdk.Controller;
The SDK provides MapResponse extension methods for converting
ServiceResult<T> into ASP.NET Core ActionResult.
📡 Basic response
[HttpGet]
public IActionResult Get()
{
var result = ServiceResult<MyDto>.Ok(data);
return this.MapResponse(result);
}
The following statuses are mapped:
ResultStatus HTTP response
Ok 200 OK
Created 201 Created
NoContent 204 No Content
PartialContent 206 Partial Content
BadRequest 400 Bad Request
NotFound 404 Not Found
InternalError 500 Internal Server Error
Error responses are converted to ServiceError.
📄 Paginated response
For:
ServiceResult<PaginatedResponse<T>>
the SDK additionally sets:
x-total-count: <total-count>
and returns the paginated data collection as the response body.
Example:
var result =
ServiceResult<PaginatedResponse<MyDto>>.Ok(
new PaginatedResponse<MyDto>
{
Data = items,
TotalCount = totalCount
});
return this.MapResponse(result);
🌐 ASP.NET Core Web API
Namespace:
using FokySdk.WebApi;
🔧 Controllers with Newtonsoft.Json
builder.Services.AddControllersWithNewtonsoft();
This registers controllers and configures Newtonsoft.Json with the SDK's standard serializer settings:
- indented JSON
- ignored null values
- UTC date format:
yyyy-MM-ddTHH:mm:ssZ
🧱 Middleware
The SDK contains several reusable ASP.NET Core middleware components.
Namespace:
using FokySdk.Middlewares;
📦 BufferingMiddleware
app.UseMiddleware<BufferingMiddleware>();
Enables request body buffering so the request body can be read by middleware and subsequently consumed by the endpoint.
This is useful when request logging needs to inspect the body.
📝 LoggingMiddleware
app.UseMiddleware<LoggingMiddleware>();
Logs HTTP method, request path, and request body through the SDK logger.
Swagger requests are excluded from body logging.
LoggingMiddleware expects FokySdk.Logging.ILogger to be registered
in dependency injection.
🏷️ VersioningMiddleware
app.UseMiddleware<VersioningMiddleware>();
Adds the following response header:
x-service-version: <SERVICE_VERSION>
If SERVICE_VERSION is not defined, the value is:
DEV
🚨 ExceptionHandlingMiddleware
app.UseMiddleware<ExceptionHandlingMiddleware>();
Provides centralized exception handling.
ApiException<ServiceError> responses are returned using the
exception's status code and ServiceError.
Unexpected exceptions are returned as:
500 Internal Server Error
Content-Type: application/json
An optional internal exception code can be configured:
ExceptionHandlingMiddleware.InternalExceptionCode = "INTERNAL_ERROR";
💡 Example application
A typical microservice can combine the SDK components like this:
using FokySdk.Controller;
using FokySdk.DataAccess;
using FokySdk.Middlewares;
using FokySdk.Swagger;
using FokySdk.Telemetry;
using FokySdk.Types.Settings;
using FokySdk.WebApi;
var builder = WebApplication.CreateBuilder(args);
var swaggerSettings = SwaggerSettings.GetFromEnvironment()
.WithJwtAuthEnabled();
builder.Services.AddControllersWithNewtonsoft();
builder.Services.AddSwagger(swaggerSettings);
builder.Services.AddEfDbContext<MyDbContext>(
EfCoreConnectionSettings.GetFromEnvironment());
builder.Services.AddOtelServices(
OtelServiceInfo.GetFromEnvironment(),
new OtelSettings
{
UseAspNetCoreInstrumentation = true,
UseHttpClientInstrumentation = true,
UseEntityFrameworkInstrumentation = true,
UseMassTransitInstrumentation = true
});
builder.Services.AddRabbitMq(
RabbitMqSettings.GetFromEnvironment(),
consumersRegister: null,
consumersAdd: null,
publishersRegister: null);
var app = builder.Build();
app.UseMiddleware<ExceptionHandlingMiddleware>();
app.UseMiddleware<VersioningMiddleware>();
app.UseMiddleware<BufferingMiddleware>();
app.AddSwagger(swaggerSettings);
app.UseAuthorization();
app.MapControllers();
app.Run();
📦 Package dependencies
The package currently uses the following major dependencies:
FokySdk.Types1.4.0MassTransit8.5.10MassTransit.RabbitMQ8.5.10Microsoft.AspNetCore.Mvc.NewtonsoftJson10.0.9Microsoft.Extensions.DependencyInjection.Abstractions10.0.9Microsoft.OpenApi2.12.2Newtonsoft.Json13.0.4NLog6.1.4Npgsql.EntityFrameworkCore.PostgreSQL10.0.3- OpenTelemetry 1.17.0
OpenTelemetry.Instrumentation.EntityFrameworkCore1.17.0-beta.1OpenTelemetry.Instrumentation.MassTransit1.0.0-beta.3- Swashbuckle ASP.NET Core 10.2.3
🔨 Building the package
Build the project:
dotnet build -c Release
Create a NuGet package:
dotnet pack ./FokySdk/FokySdk.csproj -c Release -o ./nupkgs
The project is configured with:
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
so a package is also generated during a Release build.
📜 License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- FokySdk.Types (>= 1.4.0)
- MassTransit (>= 8.5.10)
- MassTransit.RabbitMQ (>= 8.5.10)
- Microsoft.AspNetCore.Hosting.Abstractions (>= 2.3.11)
- Microsoft.AspNetCore.Mvc.NewtonsoftJson (>= 10.0.9)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.9)
- Microsoft.OpenApi (>= 2.12.2)
- Newtonsoft.Json (>= 13.0.4)
- NLog (>= 6.1.4)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 10.0.3)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.17.0)
- OpenTelemetry.Extensions.Hosting (>= 1.17.0)
- OpenTelemetry.Instrumentation.AspNetCore (>= 1.17.0)
- OpenTelemetry.Instrumentation.EntityFrameworkCore (>= 1.17.0-beta.1)
- OpenTelemetry.Instrumentation.Http (>= 1.17.0)
- OpenTelemetry.Instrumentation.MassTransit (>= 1.0.0-beta.3)
- Swashbuckle.AspNetCore.Swagger (>= 10.2.3)
- Swashbuckle.AspNetCore.SwaggerGen (>= 10.2.3)
- Swashbuckle.AspNetCore.SwaggerUI (>= 10.2.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.11.6 | 42 | 9/2/2026 |
| 1.11.5 | 40 | 9/2/2026 |
| 1.11.4 | 36 | 9/2/2026 |
| 1.11.3 | 72 | 8/31/2026 |
| 1.11.2 | 79 | 8/25/2026 |
| 1.11.1 | 59 | 8/24/2026 |
| 1.11.0 | 68 | 8/22/2026 |
| 1.10.1 | 86 | 8/22/2026 |
| 1.10.0 | 72 | 8/22/2026 |
| 1.9.0 | 65 | 8/22/2026 |
| 1.8.2 | 71 | 8/21/2026 |
| 1.8.1 | 104 | 8/16/2026 |
| 1.8.0 | 77 | 7/28/2026 |
| 1.7.1 | 115 | 7/21/2026 |
| 1.7.0 | 100 | 7/21/2026 |
| 1.6.0 | 110 | 7/19/2026 |
| 1.5.0 | 110 | 7/18/2026 |
| 1.4.11 | 141 | 6/30/2026 |
| 1.4.10 | 117 | 6/28/2026 |
| 1.4.9 | 127 | 6/26/2026 |