Essential .NET libraries that make day-to-day development simpler and safer.
- Core utilities for argument validation and fluent string checks
- Logging helpers with disposable message scopes, property accumulation, and strict LIFO enforcement
Warning
This library is currently in development and is not ready for production use.
The API is subject to breaking changes without notice. Features may be incomplete or unstable. Use at your own risk in non-production environments only.
Note
This repository targets .NET 10.0.
- Argument validation:
ThrowIfNull,ThrowIfNullOrEmpty,ThrowIfNullOrWhiteSpaceThrowIfNotDefinedfor enums
- Nullable string helpers:
IsNull,IsNullOrEmpty,IsNullOrWhiteSpace
- Logging scopes:
ILogger.BeginMessageScope(...)returning anILogMessageScope- Accumulate properties across nested scopes (child overrides parent)
- Attach exceptions and change level/message/event id before dispose
- Strict LIFO dispose with safety warning if out-of-order
Warning
Log message scopes must be disposed in LIFO order. Disposing out of order logs a warning and is ignored so a later correct dispose can succeed.
- .NET SDK 10.0+
- Clone the repository:
git clone https://github.com/jlbarreda/dev-elf.git
cd dev-elf- Restore dependencies and build:
dotnet restore
dotnet build- Run tests:
dotnet testdotnet buildRun tests:
dotnet testThis project uses a manual tag-based release process. To release a new version, maintainers create and push a git tag following semantic versioning. For detailed information, see our versioning guide.
using DevElf.ArgumentValidation;
void Process(string name, DayOfWeek day)
{
name.ThrowIfNullOrWhiteSpace(); // throws if null/empty/whitespace
day.ThrowIfNotDefined(); // throws if undefined enum value
// ... your logic
}using DevElf.Extensions;
string? input = GetInput();
if (input.IsNullOrWhiteSpace())
{
// handle missing value
}using DevElf.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
// Register once at startup
var services = new ServiceCollection()
.AddLogging(b => b.AddConsole())
.AddLogMessageScopes();
var provider = services.BuildServiceProvider();
var logger = provider.GetRequiredService<ILogger<Program>>();
// Use a disposable message scope that logs on dispose
using (var scope = logger.BeginMessageScope(LogLevel.Information, "Import completed"))
{
scope.SetProperty("CorrelationId", Guid.NewGuid());
scope.SetEventId(new EventId(1001, "Import"));
try
{
// ... do work
}
catch (Exception ex)
{
scope.SetException(ex, setProperty: true);
scope.ChangeLogLevel(LogLevel.Error);
scope.ChangeMessage("Import failed");
throw;
}
} // message written here with accumulated propertiesImportant
Properties set on nested scopes are merged. When keys conflict, the innermost scope value wins.