| status | draft | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| title | ktsu.Abstractions | ||||||||||||
| description | A library providing a comprehensive set of interfaces for compression, encoding, encryption, hashing, serialization, caching, validation, and filesystem access with zero-allocation Try* methods and convenient default implementations. | ||||||||||||
| tags |
|
A comprehensive library of interfaces that define a consistent, high-performance API for common cross-cutting concerns:
- Compression:
ICompressionProvider- compress/decompress data with Span and Stream support - Encryption:
IEncryptionProvider- encrypt/decrypt data with key and IV management - Hashing:
IHashProvider- hash data with configurable output length - Encoding:
IEncodingProvider- format/transport encoding (Base64, Hex, URL encoding) - Serialization:
ISerializationProvider- serialize/deserialize objects (JSON, YAML, TOML, etc.) - Filesystem:
IFileSystemProvider- file system operations abstraction
Each interface supports both zero-allocation Try* and Stream based methods and convenient self-allocating methods, with comprehensive async support.
This package multi-targets common frameworks for broad compatibility:
- netstandard2.1
- net5.0, net6.0, net7.0, net8.0, net9.0
Supported OS: Windows, Linux, macOS.
Via dotnet CLI:
dotnet add package ktsu.AbstractionsVia NuGet Package Manager:
Install-Package ktsu.AbstractionsVia PackageReference in csproj:
<ItemGroup>
<PackageReferenceInclude="ktsu.Abstractions"Version="1.0.0" />
</ItemGroup>Using the implementations from the ktsu.Common package via DI:
usingktsu.Abstractions;usingktsu.Common;usingMicrosoft.Extensions.DependencyInjection;IServiceCollectionservices=newServiceCollection();services.AddTransient<ICompressionProvider,ktsu.Common.GZipCompressionProvider>();services.AddTransient<IEncryptionProvider,ktsu.Common.AesEncryptionProvider>();services.AddTransient<IHashProvider,ktsu.Common.Sha256HashProvider>();services.AddTransient<IEncodingProvider,ktsu.Common.Base64EncodingProvider>();services.AddTransient<ISerializationProvider,ktsu.Common.JsonSerializationProvider>();services.AddTransient<IFileSystemProvider,ktsu.Common.FileSystemProvider>();usingIServiceProviderprovider=services.BuildServiceProvider();ICompressionProvidercompressionProvider=provider.GetRequiredService<ICompressionProvider>();IEncryptionProviderencryptionProvider=provider.GetRequiredService<IEncryptionProvider>();IHashProviderhashProvider=provider.GetRequiredService<IHashProvider>();All interfaces follow a consistent pattern:
- Core methods: Zero-allocation
Try*methods that work withSpan<byte>andStreamparameters - Convenience methods: Allocating methods that call the Try* methods and handle buffer management
- Async support:
Task-based async versions of all operations withCancellationTokensupport - String overloads: UTF8-encoded string variants for convenience
Here's how to implement a custom MD5 hash provider:
usingSystem.Security.Cryptography;usingktsu.Abstractions;publicsealedclassMyMD5HashProvider:IHashProvider{publicintHashLengthBytes=>16;// MD5 produces 128-bit (16-byte) hashes// Zero-allocation implementationpublicboolTryHash(ReadOnlySpan<byte>data,Span<byte>destination){if(destination.Length<HashLengthBytes){returnfalse;}usingvarmd5=MD5.Create();byte[]hashBytes=md5.ComputeHash(data.ToArray());hashBytes.AsSpan().CopyTo(destination);returntrue;}// Stream implementationpublicboolTryHash(Streamdata,Span<byte>destination){if(destination.Length<HashLengthBytes){returnfalse;}usingvarmd5=MD5.Create();byte[]hashBytes=md5.ComputeHash(data);hashBytes.AsSpan().CopyTo(destination);returntrue;}// All other methods (Hash(), HashAsync(), etc.) are provided by default implementations}usingSystem.Text;usingktsu.Abstractions;usingMicrosoft.Extensions.DependencyInjection;IServiceCollectionservices=newServiceCollection();services.AddTransient<IHashProvider,MyMD5HashProvider>();usingIServiceProviderprovider=services.BuildServiceProvider();IHashProviderhashProvider=provider.GetRequiredService<IHashProvider>();// Using the convenience method (allocates and manages buffer)byte[]inputData=Encoding.UTF8.GetBytes("Hello, World!");byte[]hash=hashProvider.Hash(inputData);// Using string convenience methodstringtextHash=Convert.ToHexString(hashProvider.Hash("Hello, World!"));// Using the zero-allocation Try methodSpan<byte>hashBuffer=stackallocbyte[hashProvider.HashLengthBytes];if(hashProvider.TryHash(inputData,hashBuffer)){stringresult=Convert.ToHexString(hashBuffer);}// Async usagebyte[]asyncHash=awaithashProvider.HashAsync(inputData);- Core methods support zero-allocation and streaming implementations: The fundamental operations use
Try*methods that work with caller-providedSpan<byte>orStreamdestinations, returning boolean success indicators. - Default implementations provide convenience: Interfaces include default implementations for allocating methods (
Hash(),Compress(), etc.) that handle buffer management and forward to the Try* methods. - Comprehensive async support: All operations have async variants with proper
CancellationTokensupport. - String convenience methods: UTF8-encoded string overloads are provided where appropriate for developer convenience.
- Minimal implementation burden: Implementers only need to provide the core Try* methods; all other functionality is inherited through default interface implementations.
- Implementations of
IEncryptionProvidershould rely on proven libraries (e.g., .NET BCL crypto, libsodium bindings) and follow best practices (AEAD modes, random IVs/nonces, key management). IEncodingProvideris for format/transport encodings (Base64, Hex) — these are NOT encryption and provide no security.
- Provider implementations should be stateless or internally synchronized and safe to register as singletons in DI.
- If an implementation maintains internal mutable state, document the concurrency model and recommended lifetime.
- Consistency: A single, predictable surface across implementations
- Testability: Swap implementations and mock easily, especially for filesystem
- Separation of concerns: Keep app code free of vendor-specific details
- Fork the repo and create a feature branch
- Implement or refine providers/analyzers and add tests
- Open a pull request
Licensed under the MIT License. See LICENSE.md for details.