Siemens.AspNet.MinimalApi.Sdk.Contracts
0.1.0-alpha.111
Prefix Reserved
dotnet add package Siemens.AspNet.MinimalApi.Sdk.Contracts --version 0.1.0-alpha.111
NuGet\Install-Package Siemens.AspNet.MinimalApi.Sdk.Contracts -Version 0.1.0-alpha.111
<PackageReference Include="Siemens.AspNet.MinimalApi.Sdk.Contracts" Version="0.1.0-alpha.111" />
<PackageVersion Include="Siemens.AspNet.MinimalApi.Sdk.Contracts" Version="0.1.0-alpha.111" />
<PackageReference Include="Siemens.AspNet.MinimalApi.Sdk.Contracts" />
paket add Siemens.AspNet.MinimalApi.Sdk.Contracts --version 0.1.0-alpha.111
#r "nuget: Siemens.AspNet.MinimalApi.Sdk.Contracts, 0.1.0-alpha.111"
#addin nuget:?package=Siemens.AspNet.MinimalApi.Sdk.Contracts&version=0.1.0-alpha.111&prerelease
#tool nuget:?package=Siemens.AspNet.MinimalApi.Sdk.Contracts&version=0.1.0-alpha.111&prerelease
Siemens.AspNet.MinimalApi.Sdk.Contracts
The Siemens.AspNet.MinimalApi.Sdk.Contracts
NuGet package defines essential interfaces, attributes, and base classes designed to standardize common functionalities required for building Minimal APIs. These abstractions support dependency injection, JSON serialization, difference tracking, and advanced validation scenarios.
📖 Overview
This package provides foundational contracts that facilitate a structured, extensible, and maintainable Minimal API architecture.
✅ Key Abstractions
📐 Activators
IActivator
IAsyncActivator<T>
ICustomActivator<T>
📦 JSON Serialization & Differencing
IJsonSerializer
for robust serialization and deserialization.IJsonDiffer
for detailed JSON comparison and difference detection.
✔️ Advanced Validation
IAttributeValidator
for recursive and attribute-driven validation.CustomValidatorBase<T, TAttribute>
for custom synchronous validation logic.AsyncCustomValidatorBase<T, TAttribute>
for asynchronous custom validation.Request validation abstractions:
RequestValidator<TRequest>
andAsyncRequestValidator<TRequest>
for complete object validation.PatchRequestValidator<TRequest>
andAsyncPatchRequestValidator<TRequest>
specifically tailored for PATCH scenarios.
📦 Installation
Using the .NET CLI
dotnet add package Siemens.AspNet.MinimalApi.Sdk.Contracts
⚡ Examples
Activator Usage
public class ExampleService
{
private readonly IActivator _activator;
public ExampleService(IActivator activator)
{
_activator = activator;
}
public async Task<MyClass> CreateMyClassAsync()
{
return await _activator.CreateInstanceAsync<MyClass>();
}
}
JSON Differ Example
public void CheckJsonDifferences(IJsonDiffer jsonDiffer)
{
var differences = jsonDiffer.FindDifferences("{\"name\":\"John\"}", "{\"name\":\"Jane\"}");
foreach (var diff in differences)
{
Console.WriteLine($"Property: {diff.MemberPath}, Difference: {diff.MismatchType}");
}
}
Custom Validation with Attributes
internal static class AddAlphaNumericValidatorExtension
{
internal static void AddAlphaNumericValidator(this IServiceCollection services)
{
services.AddSingletonIfNotExists<ICustomValidator, AlphaNumericValidator>();
}
}
public class AlphaNumericAttribute(params string[] sampleValues) : CustomValidationAttribute<AlphaNumericValidator>(string.Empty, sampleValues);
public sealed class AlphaNumericValidator : CustomValidatorBase<string, AlphaNumericAttribute>
{
protected override IEnumerable<ValidationErrorDetailsBase> Validate(PropertyInfo propertyInfo,
AlphaNumericAttribute attribute,
string? source)
{
if (source == null)
{
yield break;
}
if (source.Any(ch => !char.IsLetterOrDigit(ch)))
{
var sampleValues = attribute.SampleValues.Any() ? attribute.SampleValues : ["sample123"];
yield return new ValidationErrorDetailsBase
{
Errors = [$"{propertyInfo.Name} must be alphanumeric."],
Samples = sampleValues
};
}
}
}
Request Validator (sync)
This request validator shows a sample without attribute validation.
public static class AddCreateFormsConfigurationRequestValidatorExtension
{
internal static void AddCreateFormsConfigurationRequestValidator(this IServiceCollection services,
IConfiguration configuration)
{
services.AddFormsConfigurationSettings(configuration);
services.AddSingletonIfNotExists<CreateFormsConfigurationRequestValidator>();
}
}
internal sealed class CreateFormsConfigurationRequestValidator : RequestValidator<CreateFormsConfigurationRequest>
{
protected override IEnumerable<PropertyValidationResult> GetValidationErrors(CreateFormsConfigurationRequest request)
{
// Your validation code here
if (request.FormsId.IsNull())
{
var errorDetails = new ValidationErrorDetails
{
CurrentValue = request.FormsId,
Errors = [$"{nameof(request.FormsId)} must not be null. Only GUID or a long is valid for the {nameof(request.FormsId)}"],
Samples = ["a1b2c3d4-e5f6-7890-1234-567890abcdef", "1"]
};
yield return new PropertyValidationResult(nameof(request.FormsId), errorDetails);
}
}
}
Async Request Validator
In this sample the async validator is used to validate a CreateDeploymentRequest
object. The validator checks for the presence of required properties and validates them using the IAttributeValidator
interface.
public sealed record CreateDeploymentRequest
{
[ValidEnum]
public required Stage Stage { get; init; }
};
internal static class AddCreateDeploymentRequestValidatorExtension
{
internal static void AddCreateDeploymentRequestValidator(this IServiceCollection services)
{
services.AddSingletonIfNotExists<CreateDeploymentRequestValidator>();
}
}
internal sealed class CreateDeploymentRequestValidator(IAttributeValidator attributeValidator) : AsyncRequestValidator<CreateDeploymentRequest>
{
protected override async IAsyncEnumerable<PropertyValidationResult> GetValidationErrorsAsync(CreateDeploymentRequest request,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var errors = await attributeValidator.ValidateAsync(request, cancellationToken).ConfigureAwait(false);
foreach (var propertyValidationResult in errors)
{
yield return propertyValidationResult;
}
}
}
AWS DynamoDB Custom Converters
The Siemens.AspNet.MinimalApi.Sdk
already provides out of the box some helpers for the most common types. You can use them directly or implement your own converters.
Converter Name | Description |
---|---|
DateTimeOffsetConverter |
Converts DateTimeOffset values to and from string format (typically ISO 8601) for DynamoDB. |
DictionaryStringObjectConverter |
Handles conversion of Dictionary<string, object> to a DynamoDB-compatible format. |
DictionaryStringObjectNullableConverter |
Similar to DictionaryStringObjectConverter but allows nullable dictionary handling. |
ImmutableDictionaryStringObjectNullableConverter |
Converts ImmutableDictionary<string, object?> to a format compatible with DynamoDB, supporting null values. |
TimeSpanConverter |
Serializes TimeSpan values as string and deserializes them back. Useful for time duration storage in DynamoDB. |
Sample:
[DynamoDBTable("Capability")]
public record CapabilityEntity
{
[DynamoDBHashKey]
public required Guid Id { get; init; }
[DynamoDBRangeKey]
public required string DeploymentId { get; init; } = CapabilityConstants.DefaultDeploymentId;
[DynamoDBProperty(typeof(DateTimeOffsetConverter))]
public required DateTimeOffset LastUpdatedDate { get; init; } = DateTimeOffset.UtcNow;
}
AWS Dynamo Entity Mapper (POC)
The IDynamoEntityMapper
brings already most common converter with it (Siemens.AspNet.MinimalApi.Sdk). You can just use it.
In exception cases, you can implement your own converter by implementing IDynamoTypeConverter
or IAsyncDynamoTypeConverter
.
Converter Name | Description |
---|---|
EnumToStringConverter |
Converts enum values to their string representation and vice versa. Useful for storing enums as strings in DynamoDB. |
EnumerableToImmutableConverter |
Converts IEnumerable<T> to ImmutableList<T> for safe, immutable handling of collections during mapping. |
ImmutableToListConverter |
Converts ImmutableList<T> to List<T> to support serialization or mutable collection use cases. |
TimeSpanToStringConverter |
Serializes TimeSpan values as ISO 8601-like strings and parses them back. Enables human-readable time span storage. |
public sealed class MyHandler(IDynamoEntityMapper mapper)
{
public async Task<MyDto> HandleAsync(object rawData, CancellationToken cancellationToken)
{
return await mapper.ConvertAsync<MyDto>(rawData, cancellationToken);
}
}
Custom property converter example:
internal static class AddTimeSpanToStringConverterExtension
{
internal static void AddTimeSpanToStringConverter(this IServiceCollection services)
{
services.AddSingletonIfNotExists<IDynamoTypeConverter, TimeSpanToStringConverter>();
}
}
internal sealed class TimeSpanToStringConverter : IDynamoTypeConverter
{
public bool CanConvert(Type source,
Type target)
{
var canConvert = source == typeof(TimeSpan) &&
target == typeof(string);
return canConvert;
}
public object? ConvertObject(object? source,
Type targetType)
{
return source?.ToString();
}
}
📌 Usage & Best Practices
- Leverage
IActivator
for instance creation with dependency injection. - Leverage
IAsyncActivator
for instance creation with dependency injection in asynchronous contexts. - Utilize
IJsonDiffer
for tracking JSON changes in PATCH requests. - Implement custom validation logic by extending provided base validator classes.
- Implement
IAttributeValidator
custom for attribute-driven validation scenarios. - Simplified attribut-based validation by the
IAttributeValidator
interface. - Use IDynamoTypeConverter or IAsyncDynamoTypeConverter to encapsulate DynamoDB-safe conversions.
- Register custom converters and provide an implementation of IDynamoEntityMapper to centralize conversion logic.
📚 Documentation
Additional details and examples are available in the repository documentation and upcoming online resources.
📢 Contributing
Your contributions and feedback are welcomed! Please create issues or pull requests to enhance this package.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net9.0
- Newtonsoft.Json (>= 13.0.3)
- Siemens.AspNet.ErrorHandling.Contracts (>= 5.1.0-alpha.61)
- System.Linq.Async (>= 6.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Siemens.AspNet.MinimalApi.Sdk.Contracts:
Package | Downloads |
---|---|
Siemens.AspNet.MinimalApi.Sdk
A library which contains following functions: - Siemens.AspNet.MinimalApi.Sdk |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
0.1.0-alpha.111 | 0 | 5/20/2025 |
0.1.0-alpha.108 | 38 | 5/19/2025 |
0.1.0-alpha.104 | 61 | 5/18/2025 |
0.1.0-alpha.102 | 272 | 5/14/2025 |
0.1.0-alpha.101 | 183 | 5/14/2025 |
0.1.0-alpha.100 | 187 | 5/12/2025 |
0.1.0-alpha.99 | 203 | 5/12/2025 |
0.1.0-alpha.98 | 32 | 5/10/2025 |
0.1.0-alpha.97 | 28 | 5/10/2025 |
0.1.0-alpha.86 | 127 | 5/8/2025 |
0.1.0-alpha.85 | 99 | 5/8/2025 |
0.1.0-alpha.84 | 104 | 5/8/2025 |
0.1.0-alpha.82 | 115 | 5/7/2025 |
0.1.0-alpha.81 | 108 | 5/6/2025 |