Architect.AmbientContexts 1.0.0

Provides the basis for implementing the Ambient Context pattern, as well as a Clock implementation based on it.

The Ambient Context pattern is an Inversion of Control (IoC) pattern that provides static access to a dependency while controlling the dependency from the outside.
The pattern optimizes accessiblity (through statics) at the cost of transparency, making it suitable for obvious, ubiquitous, rarely-changing dependencies.

A good example is System.Transactions.TransactionScope. Any code (such as the database connector) can access the static Transaction.Current, yet outer code in the current execution flow controls it, through TransactionScopes.

By inheriting from AmbientScope, a class can become an ambient scope much like TransactionScope. When code is wrapped in such a scope (with the help of a using statement), any code inside the scope can statically access that ambient scope.

The AmbientScope base class provides fine-grained control over scope nesting (by obscuring, combining, or throwing) and supports the registration of a ubiquitous default scope.

The implementation honors logical execution flows and is async-safe.

This package also includes the ClockScope, an Ambient Context implementation for accessing the clock.

https://github.com/TheArchitectDev/Architect.AmbientContexts

There is a newer version of this package available.
See the version list below for details.
Install-Package Architect.AmbientContexts -Version 1.0.0
dotnet add package Architect.AmbientContexts --version 1.0.0
<PackageReference Include="Architect.AmbientContexts" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Architect.AmbientContexts --version 1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Architect.AmbientContexts, 1.0.0"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install Architect.AmbientContexts as a Cake Addin
#addin nuget:?package=Architect.AmbientContexts&version=1.0.0

// Install Architect.AmbientContexts as a Cake Tool
#tool nuget:?package=Architect.AmbientContexts&version=1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Architect.AmbientContexts:

Package Downloads
Architect.Identities
Reliable unique ID generation and management for distributed applications. Auto-increment IDs reveal sensitive information. UUIDs (also known as GUIDs) are inefficient as primary keys in a database. Having two different IDs is cumbersome and counterintuitive. We can do better. - For a 93-bit UUID replacement that is efficient as a primary key and has virtually no caveats, use the DistributedId. - For a 64-bit UUID replacement that is extremely efficient as a primary key, use the Fluid. - To expose IDs externally in a sensitive environment where zero metadata must be leaked, transform them with PublicIdentities. - To assign a unique ID to each distinct application or instance thereof, use an ApplicationInstanceIdSource. https://github.com/TheArchitectDev/Architect.Identities Release notes: 1.0.1: - Now using AmbientContexts 1.1.0, for a performance improvement.
Architect.EntityFramework.DbContextManagement
Manage your DbContexts the right way. https://github.com/TheArchitectDev/Architect.EntityFramework.DbContextManagement The persistence layer or infrastructure layer uses the DbContext (e.g. from a repository). Controlling its scope and transaction lifetime, however, is ideally the reponsibility of the orchestrating layer (e.g. from an application service). This package adds that ability to Entity Framework Core 5.0.0 and up. // Register public void ConfigureServices(IServiceCollection services) { services.AddPooledDbContextFactory<MyDbContext>(context => context.UseSqlServer(connectionString, sqlServer => sqlServer.EnableRetryOnFailure())); services.AddDbContextScope<MyDbContext>(); } // Consume public class MyRepository : IMyRepository { // Accesses the DbContext instance currently provided by the orchestrating layer private MyDbContext DbContext => this.DbContextAccessor.CurrentDbContext; private IDbContextAccessor<MyDbContext> DbContextAccessor { get; } public OrderRepo(IDbContextAccessor<MyDbContext> dbContextAccessor) { this.DbContextAccessor = dbContextAccessor ?? throw new ArgumentNullException(nameof(dbContextAccessor)); } public Task<Order> GetOrderById(long id) { return this.DbContext.Orders.SingleOrDefaultAsync(o.Id == id); } } // Orchestrate public class MyApplicationService { private IDbContextProvider<MyDbContext> DbContextProvider { get; } private IMyRepository MyRepository { get; } public MyApplicationService(IDbContextProvider<MyDbContext> dbContextProvider, IMyRepository myRepository) { this.DbContextProvider = dbContextProvider ?? throw new ArgumentNullException(nameof(dbContextProvider)); this.MyRepository = myRepository ?? throw new ArgumentNullException(nameof(myRepository)); } public async Task PerformSomeUnitOfWork() { // Provide a DbContext and execute a block of code within its scope await this.DbContextProvider.ExecuteInDbContextScopeAsync(async executionScope => { // Until the end of this block, IDbContextAccessor can access the scoped DbContext // It can do so from any number of invocations deep (not shown here) await this.MyRepository.AddOrder(new Order()); // If we have made modifications, we should save them // We could save here or as part of the repository methods, depending on our preference await executionScope.DbContext.SaveChangesAsync(); }); // If no exceptions occurred and this scope was not nested in another, the transaction is committed asynchronously here } }

GitHub repositories

This package is not used by any popular GitHub repositories.

Version History

Version Downloads Last updated
1.1.0 123 9/12/2021
1.1.0-preview-20210912.1 91 9/12/2021
1.0.0 1,935 12/7/2020