DRN.Framework.Utils
0.7.0-preview059
Prefix Reserved
See the version list below for details.
dotnet add package DRN.Framework.Utils --version 0.7.0-preview059
NuGet\Install-Package DRN.Framework.Utils -Version 0.7.0-preview059
<PackageReference Include="DRN.Framework.Utils" Version="0.7.0-preview059" />
<PackageVersion Include="DRN.Framework.Utils" Version="0.7.0-preview059" />
<PackageReference Include="DRN.Framework.Utils" />
paket add DRN.Framework.Utils --version 0.7.0-preview059
#r "nuget: DRN.Framework.Utils, 0.7.0-preview059"
#:package DRN.Framework.Utils@0.7.0-preview059
#addin nuget:?package=DRN.Framework.Utils&version=0.7.0-preview059&prerelease
#tool nuget:?package=DRN.Framework.Utils&version=0.7.0-preview059&prerelease
DRN.Framework.Utils
Core utilities package providing attribute-based dependency injection, configuration management, scoped logging, ambient context, and essential extensions.
TL;DR
- Attribute DI -
[Scoped<T>],[Singleton<T>],[Transient<T>]for zero-config service registration - Configuration -
IAppSettingswith typed access,[Config("Section")]bindings - Scoped Logging -
IScopedLogaggregates structured logs per request - Ambient Context -
ScopeContext.UserId,ScopeContext.Settingsanywhere - Auto-Registration -
AddServicesWithAttributes()scans and registers all attributed services
Table of Contents
- QuickStart: Beginner
- QuickStart: Advanced
- Setup
- Dependency Injection
- Configuration
- Logging (IScopedLog)
- HTTP Client Factories
- Scope & Ambient Context
- Data Utilities
- Utilities
- Extensions
QuickStart: Beginner
Register and use a service with attribute-based DI:
// 1. Define your service with DI attribute
public interface IGreetingService { string Greet(string name); }
[Scoped<IGreetingService>]
public class GreetingService : IGreetingService
{
public string Greet(string name) => $"Hello, {name}!";
}
// 2. Register all attributed services in Startup
services.AddServicesWithAttributes();
// 3. Inject and use
public class HomeController(IGreetingService greetingService) : Controller
{
public IActionResult Index() => Ok(greetingService.Greet("World"));
}
QuickStart: Advanced
Complete example with configuration binding, scoped logging, and ambient context:
// Bind configuration section to strongly-typed class
[Config("PaymentSettings")]
public class PaymentSettings
{
public string ApiKey { get; set; } = "";
public int TimeoutSeconds { get; set; } = 30;
}
// Service using scoped logging and settings
[Scoped<IPaymentService>]
public class PaymentService(IAppSettings settings, IScopedLog log, PaymentSettings config) : IPaymentService
{
public async Task<PaymentResult> ProcessAsync(decimal amount)
{
// Track execution time
using var duration = log.Measure("PaymentProcessing");
// Add structured context
log.Add("Amount", amount);
log.AddToActions("Processing payment");
// Access ambient data anywhere
var userId = ScopeContext.UserId;
// Use typed configuration
if (config.TimeoutSeconds < 10)
throw ExceptionFor.Configuration("Timeout too short");
return new PaymentResult(Success: true);
}
}
Setup
If you are using DRN.Framework.Hosting (inheriting from DrnProgramBase), this package is automatically registered and validated.
For manual installation (e.g. Console Apps, Workers):
// Registers attributes, HybridCache, and TimeProvider
builder.Services.AddDrnUtils();
Dependency Injection
Attribute-Based Registration
Reduce wiring code by using attributes directly on your services. The registration method scans the calling assembly for these attributes.
| Attribute | Lifetime | Usage |
|---|---|---|
[Singleton<T>] |
Singleton | [Singleton<IMyService>] public class MyService : IMyService |
[Scoped<T>] |
Scoped | [Scoped<IMyService>] public class MyService : IMyService |
[Transient<T>] |
Transient | [Transient<IMyService>] public class MyService : IMyService |
[ScopedWithKey<T>] |
Scoped (Keyed) | [ScopedWithKey<IMyService>("key")] |
Validation & Testing
DrnProgramBase automatically runs this validation at startup.
You can manually validate that all attribute-marked services are resolvable:
// In Program.cs
app.Services.ValidateServicesAddedByAttributes();
In integration tests with DRN.Framework.Testing:
[Theory, DataInlineContext]
public void Validate_Dependencies(DrnTestContext context)
{
context.ServiceCollection.AddServicesWithAttributes(); // Register local assembly
context.ValidateServices(); // Verifies resolution of all registered descriptors
}
Module Registration & Startup Actions
Services can require complex registration logic or post-startup actions. Attributes inheriting from ServiceRegistrationAttribute handle this.
Example: DrnContext<T> (in DRN.Framework.EntityFramework) is decorated with [DrnContextServiceRegistration], which:
- Registers the DbContext.
- Automatically triggers EF Core Migrations when the application starts in Development environments (via
PostStartupValidationAsync).
// The base class DrnContext handles the registration attributes.
// You just inherit from it, and your context is auto-registered with migration support.
public class MyDbContext : DrnContext<MyDbContext> { }
Configuration
IAppSettings
Access configuration safely with typed environments and utility methods.
public class MyService(IAppSettings settings)
{
public void DoWork()
{
if (settings.IsDevEnvironment) { ... }
var conn = settings.GetRequiredConnectionString("Default");
var value = settings.GetValue<int>("MySettings:Timeout", 30);
}
}
Configuration Attributes ([Config])
Bind classes directly to configuration sections. These are registered as Singletons.
[Config("PaymentSettings")] // Binds to "PaymentSettings" section
public class PaymentOptions
{
public string ApiKey { get; set; }
}
[Config] // Binds to "FeatureFlags" section (class name)
public class FeatureFlags { ... }
[ConfigRoot] // Binds to root configuration
public class RootSettings { ... }
Configuration Sources
The framework automatically loads configuration in this order:
appsettings.json/appsettings.{Environment}.json- Environment Variables
- Mounted Settings:
/appconfig/json-settings/*.json/appconfig/key-per-file-settings/*
Override the mount directory by registering IMountedSettingsConventionsOverride.
Logging (IScopedLog)
IScopedLog provides request-scoped structured logging. It aggregates logs, metrics, and actions throughout the request lifetime and flushes them as a single structured log entry at the end, making it ideal for high-traffic observability and performance monitoring.
Core Features
- Contextual: Automatically captures
TraceId,UserId,RequestPath, and custom scope data. - Aggregation: Groups all actions, metrics, and exceptions into a single structured log entry.
- Performance Tracking: Built-in measurement for code block durations and execution counts.
- Resilience: Captures exceptions without interrupting the business flow unless explicitly thrown.
API Usage
public class OrderService(IScopedLog logger)
{
public void ProcessOrder(int orderId)
{
// 1. Measure execution time and count
// Automatically tracks duration and increments "Stats_ProcessOrder_Count"
using var _ = logger.Measure("ProcessOrder");
// 2. Add structured data (Key-Value)
logger.Add("OrderId", orderId);
logger.AddIfNotNullOrEmpty("Referrer", "PartnerA");
// 3. Track execution checkpoints
logger.AddToActions("Validating order");
try
{
// ... logic ...
// 4. Flatten and add complex objects
logger.AddProperties("User", new { Name = "John", Role = "Admin" });
}
catch(Exception ex)
{
// 5. Log exception but keep the request contextual log intact
logger.AddException(ex, "Failed to process order");
}
}
}
HTTP Client Factories (IExternalRequest, IInternalRequest)
Lightweight wrappers around Flurl for consistent, resilient HTTP client configuration with built-in JSON convention support.
External Requests
Use IExternalRequest for standard external API calls. It pre-configures DefaultJsonSerializer and enforces HTTP version policies.
public class PaymentService(IExternalRequest request)
{
public async Task Process()
{
// Enforces exact HTTP version for better compatibility with modern APIs
var response = await request.For("https://api.example.com", HttpVersion.Version11)
.AppendPathSegment("v1/charges")
.PostJsonAsync(new { Amount = 1000 })
.ToJsonAsync<ExternalApiResponse>();
}
}
Internal Requests (Service Mesh)
Use IInternalRequest for Service-to-Service communication in Kubernetes. It's designed to work with Linkerd/Istio, supporting automatic protocol switching (HTTP/HTTPS) based on infrastructure settings.
Recommended Pattern: Request Wrappers
Instead of using IInternalRequest directly in business logic, wrap it in a typed request factory for better maintainability and configuration encapsulation.
// 1. Definition (External Factory Wrapper)
public interface INexusRequest { IFlurlRequest For(string path); }
[Singleton<INexusRequest>]
public class NexusRequest(IInternalRequest request, IAppSettings settings) : INexusRequest
{
private readonly string _nexusAddress = settings.NexusAppSettings.NexusAddress;
public IFlurlRequest For(string path) => request.For(_nexusAddress).AppendPathSegment(path);
}
// 2. Client Usage
public class NexusClient(INexusRequest request) : INexusClient
{
public async Task<HttpResponse<string>> GetStatusAsync() =>
await request.For("status").GetAsync().ToStringAsync();
}
Scope & Ambient Context (ScopeContext)
ScopeContext provides ambient (static) access to scoped information within a valid execution context (like an HTTP request). This is ideal for cross-cutting concerns like auditing, multi-tenancy, or security where deep parameter passing is undesirable.
- Contextual Identity: Access
UserId,TraceId, andAuthenticatedstatus anywhere. - Static Accessors: Provides direct access to
IAppSettings,IScopedLog, andIServiceProvider. - RBAC Helpers: Built-in support for role and claim checks.
var currentUserId = ScopeContext.UserId;
var traceId = ScopeContext.TraceId;
var settings = ScopeContext.Settings; // Static IAppSettings access
var logger = ScopeContext.Log; // Static IScopedLog access
if (ScopeContext.IsUserInRole("Admin")) { ... }
Data Utilities
Encodings (EncodingExtensions)
Unified API for binary-to-text encodings and model serialization-encoding.
- Encodings: Base64, Base64Url (Safe for URLs), Hex, and Utf8.
- Integrated:
model.Encode(ByteEncoding.Hex)andhexString.Decode<TModel>().
Hashing (HashExtensions)
High-performance hashing extensions supporting modern and legacy algorithms.
- Blake3: Default modern cryptographic hash (fast and secure).
- XxHash3: Non-cryptographic hashing for performance-critical scenarios (IDs, Cache keys).
- Security: Keyed hashing support (
HashWithKey) for integrity protection.
JSON & Document Utilities
- JSON Merge Patch:
JsonMergePatch.SafeApplyMergePatchfollows RFC 7386 for partial updates with built-in recursion depth protection. - Query String Serialization:
QueryParameterSerializerflattens complex nested objects/arrays into clean query strings for API clients.
Serialization & Streams
- Unified Extensions:
model.Serialize(method)supports both JSON and Query String formats. - Safe Stream Consumption:
ToBinaryDataAsyncandToArrayAsyncextensions withMaxSizeGuardto prevent memory exhaustion from untrusted streams.
Validation
Extensions for programmatic validation using System.ComponentModel.DataAnnotations.
- Contextual: Integrates with
DRN.Framework.SharedKernel.ValidationExceptionfor standardized error reporting across layers.
// Multi-format serialization
var json = model.Serialize(SerializationMethod.SystemTextJson);
var query = model.Serialize(SerializationMethod.QueryString);
// Data Integrity
var hash = data.Hash(HashAlgorithm.Blake3);
// Secure stream conversion
var bytes = await requestStream.ToBinaryDataAsync(maxSize: 1024 * 1024);
Utilities
ID Generation & Validation
SourceKnownEntity ID's provide reversible, type-safe, and integrity-checked identifiers.
ID generation is automatically handled by DrnContext when SourceKnownEntities are saved.
Users can validate incoming IDs (e.g., from APIs) using multiple approaches depending on the context:
1. Injectable Utility (Recommended for Service Layer)
var sourceKnownId = sourceKnownEntityIdUtils.Validate<User>(externalGuidId);
2. SourceKnownRepository (Recommended for Data Access)
// Method on SourceKnownRepository<TEntity>
var sourceKnownId = userRepository.GetEntityId(externalGuidId);
3. SourceKnownEntity (Recommended for Domain Logic)
// Helper on SourceKnownEntity base class
var sourceKnownId = userInstance.GetEntityId<User>(externalGuidId);
Time
TimeProvider singleton is registered by default to TimeProvider.System for testable time entry.
Extensions
Comprehensive set of extensions for standard .NET types and reflection.
Reflection & MethodUtils
Highly optimized reflection helpers with built-in caching for generic and non-generic method invocation.
- Invoke:
instance.InvokeMethod("Name", args)andtype.InvokeStaticMethod("Name", args). - Generics:
instance.InvokeGenericMethod("Name", typeArgs, args)with static and uncached variations. - Caching: Uses internal
ConcurrentDictionaryandrecord structkeys for zero-allocation cache lookups.
Service Collection
Advanced DI container manipulation for testing and modularity.
- Querying:
sc.GetAllAssignableTo<TService>()retrieves all descriptors matching a type. - Replacement:
ReplaceScoped,ReplaceSingleton, andReplaceInstancefor mocking/overriding dependencies in integration tests.
String Extensions
- Casing:
ToSnakeCase,ToCamelCase, andToPascalCasefor clean code-to-external system mapping. - Parsing:
string.Parse<T>()andstring.TryParse<T>(out result)using the modernIParsable<T>interface. - Binary:
ToStream()andToByteArray()shortcuts with UTF8 default.
Type & Assembly Extensions
- Discovery:
assembly.GetSubTypes(typeof(T))andassembly.GetTypesAssignableTo(to). - Instantiation:
assembly.CreateSubTypes<T>()automatically discovers and instantiates classes with parameterless constructors. - Metadata:
type.GetAssemblyName()returns a clean assembly name.
Object & Dictionary Extensions
- Deep Discovery:
instance.GetGroupedPropertiesOfSubtype(type)recursively finds properties matching a base type across complex object graphs. - Dictionary Utility: Extensions for
IDictionaryto handle null-safe value retrieval and manipulation.
// Discovery and Instantiation
var implementations = typeof(IMyInterface).Assembly.CreateSubTypes<IMyInterface>();
// Modern Parsing
int value = "123".Parse<int>();
// Casing for APIs
var key = "MyPropertyName".ToSnakeCase(); // my_property_name
Semper Progressivus: Always Progressive
Commit Info
Author: Duran Serkan KILIÇ
Date: 2026-01-26 21:12:39 +0300
Hash: 858b6f431aa962dcd742ffa77fa3a94322c3754e
| 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
- Blake3 (>= 2.2.0)
- DRN.Framework.SharedKernel (>= 0.7.0-preview059)
- Flurl.Http (>= 4.0.2)
- Microsoft.EntityFrameworkCore (>= 10.0.2)
- Microsoft.Extensions.Caching.Hybrid (>= 10.2.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.2)
- Microsoft.Extensions.Configuration.Json (>= 10.0.2)
- Microsoft.Extensions.DependencyInjection (>= 10.0.2)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.2)
- Microsoft.Extensions.Identity.Stores (>= 10.0.2)
- System.IO.Hashing (>= 10.0.2)
- System.Memory.Data (>= 10.0.2)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on DRN.Framework.Utils:
| Package | Downloads |
|---|---|
|
DRN.Framework.EntityFramework
DRN.Framework.EntityFramework provides DrnContext with conventions to develop rapid and effective domain models. ## Commit Info Author: Duran Serkan KILIÇ Date: 2026-03-14 17:32:18 +0300 Hash: 9ef739ee5aaa5d5507ba19619770bf86581ed4e4 |
|
|
DRN.Framework.Hosting
DRN.Framework.Hosting ## Commit Info Author: Duran Serkan KILIÇ Date: 2026-03-14 17:32:18 +0300 Hash: 9ef739ee5aaa5d5507ba19619770bf86581ed4e4 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.8.0 | 27 | 3/14/2026 |
| 0.7.0 | 98 | 3/8/2026 |
| 0.7.0-preview067 | 104 | 3/7/2026 |
| 0.7.0-preview066 | 119 | 2/28/2026 |
| 0.7.0-preview065 | 113 | 2/25/2026 |
| 0.7.0-preview064 | 105 | 2/22/2026 |
| 0.7.0-preview063 | 110 | 2/21/2026 |
| 0.7.0-preview062 | 114 | 2/11/2026 |
| 0.7.0-preview061 | 131 | 2/7/2026 |
| 0.7.0-preview060 | 113 | 1/28/2026 |
| 0.7.0-preview059 | 113 | 1/26/2026 |
| 0.7.0-preview058 | 116 | 1/25/2026 |
| 0.7.0-preview057 | 114 | 1/25/2026 |
| 0.7.0-preview056 | 118 | 1/10/2026 |
| 0.7.0-preview055 | 290 | 12/16/2025 |
| 0.7.0-preview054 | 196 | 12/13/2025 |
| 0.7.0-preview053 | 140 | 12/12/2025 |
| 0.7.0-preview052 | 450 | 12/9/2025 |
| 0.7.0-preview051 | 324 | 12/7/2025 |
| 0.7.0-preview050 | 241 | 12/7/2025 |
Not every version includes changes, features or bug fixes. This project can increment version to keep consistency with other DRN.Framework projects.
## Version 0.6.0
My family celebrates the enduring legacy of Mustafa Kemal Atatürk's enlightenment ideals. This release is dedicated to the memory of Mustafa Kemal Atatürk, founder of the Republic of Türkiye, and to his vision for a modern, enlightened, democratic nation. In his eternal rest, he continues to guide us through his ideals of freedom, progress, and national sovereignty.
### New Features
* ScopeContext
* IScopeLog, IScopeUser, ServiceProvider, AppSettings added with utility properties for fast access
* ClaimConventions and MfaFor utility classes added to verify MultiFactorAuthentication
### Breaking Changes
* ScopeContext, ScopedUser and ClaimGroup
* Refactored with usability and security improvements
* InternalRequest, ExternalRequest
* HttpRequestMessage VersionPolicy set as Request version exact.
* AppSettings.Instance method removed. AppSettings can be accessed with ScopeContext in static context
## Version 0.5.0
My family celebrates the enduring legacy of Mustafa Kemal Atatürk's enlightenment ideals. This release is dedicated to August 30 Victory Day, a day that marks the decisive victory achieved by the Turkish people against imperialism during the Turkish War of Independence, leading to the establishment of the Republic of Türkiye.
### New Features
* IScopedUser, ScopedUserSummary and ScopeContext added
* IScopedLog
* TraceIdentifier support
* Inner exception support
* Flurl exception support
* IExternalRequest - Added with singleton lifetime as request factory for external requests
* IAppSettings.DrnAppFeatures
* UseHttpRequestLogger Flag
* LaunchExternalDependencies Flag
* NexusAddress Url property
## Version 0.4.0
My family celebrates the enduring legacy of Mustafa Kemal Atatürk's enlightenment ideals. This release is dedicated to 19 May Commemoration of Atatürk, Youth and Sports Day.
### Breaking Changes
* AttributeSpecifiedServiceCollectionModule - renamed as AttributeSpecifiedServiceModule
* HasServiceCollectionModuleAttribute - renamed as ServiceRegistrationAttribute
* HasDrnContextServiceCollectionModuleAttribute - renamed as DrnContextServiceRegistrationAttribute
* ServiceRegistrationAttribute MethodInfo property - replaced with ServiceRegistration method to make usage strongly typed and support inheritance
### New Features
* DrnAppFeatures property - added to IAppSettings
* InternalRequestHttpVersion can be set as "1.1" or "2.0"
* InternalRequestProtocol can be set as "http" or "https ""
* IInternalRequest and InternalRequest - added to generate internal Flurl requests with configurable **Linkerd compatible** sensible defaults
* HttpResponse and following flurl response extensions - added to fluently get strongly typed response and flurl response together:
* ToStringAsync
* ToBytesAsync
* ToStreamAsync
* ToJsonAsync<TResponse>
## Version 0.3.0
My family celebrates the enduring legacy of Mustafa Kemal Atatürk's enlightenment ideals. This release is dedicated to 23 April National Sovereignty and Children's Day.
### New Features
* AppSettings now has GetDebugView() method that returns ConfigurationDebugView
* ConfigurationDebugView has ToSummary() method that returns human friendly configuration summary model.
* AppSettings now has GetValue<> and Get<> methods to get values from configuration
* MountedSettingsConventions added.
* /appconfig/json-settings json files will be added to configuration if any exist
* /appconfig/key-per-file-settings files will be added to configuration if any exist
* IMountedSettingsConventionsOverride overrides default /appconfig location if added to service collection before host built
* HasServiceCollectionModuleAttribute has PostStartupValidationAsync when,
* ValidateServicesAddedByAttributes extension method called from service provider,
* PostStartupValidationAsync will be called if all services resolved successfully.
* For instance, DrnContext can apply migrations after service provider services resolved successfully.
* ScopedLog and IScopedLog added to aggregate related log within a scope such as a http request.
## Version 0.2.0
### Breaking Changes
* LifetimeContainer renamed as DrnServiceContainer
* Lifetime attributes moved to DRN.Framework.Utils.DependencyInjection.Attributes namespace
### New Features
* JsonSerializerConfigurationSource - added to add dotnet objects to configuration
* RemoteJsonConfigurationSource - added to remote settings to configuration (experimental)
* ConnectionStringsCollection - added as poco model to serialize connection strings
* StringExtensions
* ToStream method added to convert strings to in memory stream
* HasServiceCollectionModuleAttribute
## Version 0.1.0
### New Features
* AppSettings
* ServiceCollectionExtensions
* ReplaceInstance
* ReplaceTransient
* ReplaceScoped
* ReplaceSingleton
* Attribute based dependency injection
* ScopedAttribute, TransientAttribute, SingletonAttribute and LifetimeAttribute
* ScopedWithKeyAttribute, TransientWithKeyAttribute, SingletonWithKeyAttribute and LifetimeWithKeyAttribute
* ServiceCollection AddServicesWithAttributes extension
* ServiceProvider ValidateServicesAddedByAttributes extension
---
**Semper Progressivus: Always Progressive**
## Commit Info
Author: Duran Serkan KILIÇ
Date: 2026-01-26 21:12:39 +0300
Hash: 858b6f431aa962dcd742ffa77fa3a94322c3754e