CodeMe.Basics 0.0.3

dotnet add package CodeMe.Basics --version 0.0.3
                    
NuGet\Install-Package CodeMe.Basics -Version 0.0.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CodeMe.Basics" Version="0.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CodeMe.Basics" Version="0.0.3" />
                    
Directory.Packages.props
<PackageReference Include="CodeMe.Basics" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CodeMe.Basics --version 0.0.3
                    
#r "nuget: CodeMe.Basics, 0.0.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CodeMe.Basics@0.0.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CodeMe.Basics&version=0.0.3
                    
Install as a Cake Addin
#tool nuget:?package=CodeMe.Basics&version=0.0.3
                    
Install as a Cake Tool

CodeMe.Basics

CodeMe.Basics is a library for simple reusable infrastructure types that are missing in BCL.

ScopedAsyncLocal<T>

ScopedAsyncLocal<T> provides ambient context for a logical execution flow. It is useful when a value should be available to all code in the current flow without explicitly passing it through every method call. Typical scenarios include unit of work scopes, request correlation identifiers, tenant information, etc.

Scenarios and example of usage

Use ScopedAsyncLocal<T> when a value should be available to the current logical execution path and reverted automatically when the scope ends. The value is visible to nested scopes and is restored to the previous ambient value when the scope is disposed.

using CodeMe.Basics.Threading;

var context = new ScopedAsyncLocal<string>();

using (context.BeginScope("request-1"))
{
    Console.WriteLine(context.Current); // request-1

    using (context.BeginScope("nested"))
    {
        Console.WriteLine(context.Current); // nested
    }

    Console.WriteLine(context.Current); // request-1
}

Console.WriteLine(context.Current); // null

n t ScopedAsyncLocal<T> also works with asynchronous flows. The value from the current scope is available after await; the scope must be disposed to restore the previous value.

var local = new ScopedAsyncLocal<string>();

using (await local.BeginScopeAsync(() => new ValueTask<string>("request-2")))
{
    Console.WriteLine(local.Current); // request-2
}

The constructor can be used with validateDisposeOrder: true to detect out-of-order scope disposal.

Using BeginScopeAsync from helper methods

BeginScopeAsync initializes the scope asynchronously through a value factory. If you call it from a helper method, keep the helper synchronous and avoid await in the call. Otherwise new scope will not be propagated back to the caller. The value factory itself may use await.

    private Task<IDisposable> BeginUnitOfWorkAsync(
        ScopedAsyncLocal<IUnitOfWork> local,
        CancellationToken cancellation = default) =>
        local.BeginScopeAsync(
            async () =>
            {
                // The body is simplified for demonstration purposes.
                DbConnection? connection = null;
                DbTransaction? transaction = null;
                try
                {
                    connection = await _connectionFactory.CreateConnectionAsync(cancellation);
                    await connection.OpenAsync(cancellation);
                    transaction = await connection.BeginTransactionAsync(cancellation);

                    return new UnitOfWork(connection, transaction);
                }
                catch (Exception ex)
                {
                    if (transaction != null)
                    {
                        await transaction.DisposeAsync();
                    }

                    if (connection != null)
                    {
                        await connection.DisposeAsync();
                    }

                    throw;
                }
            });

Documentation

Check documentation for more details and examples.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

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
0.0.3 93 7/12/2026