AzureBlast 2.1.1
dotnet add package AzureBlast --version 2.1.1
NuGet\Install-Package AzureBlast -Version 2.1.1
<PackageReference Include="AzureBlast" Version="2.1.1" />
<PackageVersion Include="AzureBlast" Version="2.1.1" />
<PackageReference Include="AzureBlast" />
paket add AzureBlast --version 2.1.1
#r "nuget: AzureBlast, 2.1.1"
#:package AzureBlast@2.1.1
#addin nuget:?package=AzureBlast&version=2.1.1
#tool nuget:?package=AzureBlast&version=2.1.1
AzureBlast
![]()
AzureBlast is a lightweight, injectable .NET library that simplifies working with Azure services—including SQL Server, Service Bus, Key Vault, Table Storage, and ARM (Resource Manager)—from applications, scripts, and tools. It’s designed to be DI-friendly and easy to unit test.
✨ Features
- MSSQL – simple API for parameterized queries and metadata loading.
- Azure Service Bus – send single/batch/scheduled messages; receive & complete.
- Azure Key Vault – initialize a vault and get/set/delete/purge secrets.
- Azure Table Storage – list tables, set a table, upsert/query/delete entities.
- Azure Resource Manager (ARM) – list subscriptions, set subscription context, query resources.
- Two DI styles – options-based
AddAzureBlast(...)or a fluent builder viaUseAzureBlast(...). - Vault-agnostic resolver path (new in 2.1) – reference connections by logical name and let any
Func<category, key, ct, Task<string>>delegate (e.g.Secrets.Resolverfrom TaskBlaster / SecretBlast) hydrate the values. - Script-friendly –
AzureBlastFactoryfor LINQPad/PowerShell/console scenarios. - Testable – interfaces and adapters to mock sealed SDK types.
📦 Installation
dotnet add package AzureBlast
Targets .NET 8+. Authentication defaults to
DefaultAzureCredentialunless you supply aTokenCredential.
🔐 Authentication
By default, AzureBlast uses DefaultAzureCredential. You can pass a custom TokenCredential if you need a specific auth flow (client secret, managed identity from a particular resource, etc.).
using Azure.Identity;
var cred = new ClientSecretCredential(tenantId, clientId, clientSecret);
🧰 Choose your setup
1) Options-based DI registration (one-shot)
using AzureBlast;
using Microsoft.Extensions.DependencyInjection;
using Azure.Identity; // only if you override Credential
var services = new ServiceCollection();
services.AddAzureBlast(o =>
{
o.SqlConnectionString = "Server=.;Database=App;Trusted_Connection=True;";
o.KeyVaultUrl = "https://contoso.vault.azure.net/";
o.TableStorageConnectionString = "UseDevelopmentStorage=true;";
o.TableName = "MyTable";
o.ServiceBusConnectionString = "<sb-connection-string>";
o.ServiceBusQueueName = "orders";
// Optional credential override (otherwise DefaultAzureCredential is used):
// o.Credential = new DefaultAzureCredential();
});
var sp = services.BuildServiceProvider();
This path uses
TryAdd*so your own prior registrations aren’t overwritten.
2) Fluent builder (incremental)
using AzureBlast;
using Microsoft.Extensions.DependencyInjection;
using Azure.Identity;
var services = new ServiceCollection();
// DefaultAzureCredential:
services
.UseAzureBlast()
.WithSql("Server=.;Database=App;Trusted_Connection=True;")
.WithKeyVault("https://contoso.vault.azure.net/")
.WithTableStorage("UseDevelopmentStorage=true;", "MyTable")
.WithServiceBus("<sb-connection-string>", "orders")
.Build();
// Or supply a custom TokenCredential:
services
.UseAzureBlast(new DefaultAzureCredential())
.WithKeyVault("https://contoso.vault.azure.net/")
.Build();
var sp = services.BuildServiceProvider();
3) Resolver-driven (vault-backed connection lookup) — new in 2.1
If you store connection details in a vault (or any other secret store), wire a
Func<category, key, ct, Task<string>> resolver delegate and reference each
connection by a logical name. AzureBlast pulls the values at registration time;
the library itself stays free of any vault dependency.
using AzureBlast;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddAzureBlast(o =>
{
// Wire your resolver — typically Secrets.Resolver from TaskBlaster / SecretBlast.
o.Resolver = (category, key, ct) => myVault.ResolveAsync(category, key, ct);
// Reference connections by logical name; values come from the resolver:
o.SqlConnectionName = "azure-prod-sql"; // → (azure-prod-sql, "connectionString")
o.ServiceBusConnectionName = "orders"; // → (orders, "connectionString" + "queueName")
o.TableConnectionName = "events"; // → (events, "connectionString" + "tableName")
o.KeyVaultConnectionName = "kv-prod"; // → (kv-prod, "url")
});
You can mix the resolver path with the string path freely — set whichever fields make sense per component. The resolver path takes precedence when both are configured for the same component.
You can also call the resolver-aware overloads directly on a component you build by hand:
var db = new MssqlDatabase();
await db.SetupAsync(myVault.ResolveAsync, "azure-prod-sql");
var sb = new AzureServiceBus();
await sb.SetupAsync(myVault.ResolveAsync, "orders");
var tbl = new AzureTableStorage();
await tbl.InitializeAsync(myVault.ResolveAsync, "events");
var kv = new AzureKeyVault(new DefaultAzureCredential());
await kv.InitializeKeyVaultAsync(myVault.ResolveAsync, "kv-prod");
Each overload accepts optional *Key parameters for callers whose vault uses
non-default field names (e.g. connectionStringKey: "dsn").
4) Adhoc (no DI) via AzureBlastFactory — scripts, LINQPad, PowerShell
using AzureBlast;
// Build a provider ad-hoc with options (no IServiceCollection needed)
var sp = AzureBlastFactory.CreateServiceProvider(o =>
{
o.TableStorageConnectionString = "UseDevelopmentStorage=true;";
o.TableName = "MyTable";
});
// Or construct exactly what you need, directly:
var db = AzureBlastFactory.CreateDatabase("Server=.;Database=App;Trusted_Connection=True;");
var kv = AzureBlastFactory.CreateKeyVault("https://contoso.vault.azure.net/"); // or CreateKeyVaultAsync(...)
var sb = AzureBlastFactory.CreateServiceBus("<sb-conn>", "orders");
var ts = AzureBlastFactory.CreateTableStorage("UseDevelopmentStorage=true;", "MyTable");
var arm = AzureBlastFactory.CreateArmClientWrapper();
var rc = AzureBlastFactory.CreateResourceClient();
🧪 Using the services
All interfaces live under
AzureBlast.Interfaces.
SQL (IMssqlDatabase)
using AzureBlast.Interfaces;
var db = sp.GetRequiredService<IMssqlDatabase>();
var rowsAffected = db.ExecuteNonQuery(
"UPDATE Users SET IsActive = @active WHERE Id = @id",
new() { ["@active"] = true, ["@id"] = 42 });
var result = db.ExecuteScalar(
"SELECT COUNT(*) FROM Users WHERE IsActive = @active",
new() { ["@active"] = true });
Service Bus (IAzureServiceBus)
using AzureBlast.Interfaces;
// Resolve from DI (already configured via options/fluent)
var bus = sp.GetRequiredService<IAzureServiceBus>();
// Send a message
await bus.SendMessageAsync("""{ "type": "hello", "payload": "AzureBlast" }"" );
// Receive some messages
var received = await bus.ReceiveMessagesAsync(maxMessages: 10);
foreach (var msg in received ?? [])
{
// ...process...
await bus.CompleteMessageAsync(msg);
}
Key Vault (IAzureKeyVault)
using AzureBlast.Interfaces;
var kv = sp.GetRequiredService<IAzureKeyVault>();
await kv.SetSecretAsync("MySecret", "shh");
var value = await kv.GetSecretAsync("MySecret");
// value == "shh"
Table Storage (IAzureTableStorage)
using AzureBlast.Interfaces;
using Azure.Data.Tables;
var tables = sp.GetRequiredService<IAzureTableStorage>();
// Optional: switch table at runtime
tables.SetTable("MyTable");
// Define an entity
public class UserEntity : ITableEntity
{
public string PartitionKey { get; set; } = "Users";
public string RowKey { get; set; } = Guid.NewGuid().ToString("N");
public string Name { get; set; } = default!;
public bool IsActive { get; set; }
public DateTimeOffset? Timestamp { get; set; }
public ETag ETag { get; set; }
}
// Upsert
await tables.UpsertEntityAsync(new UserEntity { Name = "Ada", IsActive = true });
// Query
var users = await tables.QueryEntitiesAsync<UserEntity>("IsActive eq true");
// Get & Delete
var first = users.FirstOrDefault();
if (first is not null)
{
var fetched = await tables.GetEntityAsync<UserEntity>(first.PartitionKey, first.RowKey);
await tables.DeleteEntityAsync(first.PartitionKey, first.RowKey);
}
ARM / Resource Graph (IAzureResourceClient)
using AzureBlast.Interfaces;
// Always available; wrapper is registered by default.
var rc = sp.GetRequiredService<IAzureResourceClient>();
// List subscriptions and set the one you want
var subs = await rc.ListSubscriptionsAsync();
var subId = subs.First().Id.SubscriptionId!;
await rc.SetSubscriptionContextAsync(subId);
// Explore resources
var groups = await rc.GetResourceGroupsByTagAsync("env", "prod");
var vms = await rc.GetResourcesByTypeAsync("Microsoft.Compute/virtualMachines");
var exists = await rc.ResourceExistsAsync("rg-app", "my-app-plan");
🧪 Testing
- The DI registration via options uses
TryAdd*so repeated calls don’t duplicate registrations and won’t overwrite your own. - Service Bus, Table Storage, and ARM are exposed through interfaces and adapters so you can stub or mock them in unit tests.
- Example: provide a fake
IAzureTableStoragein the test container and assert it’s preserved when callingAddAzureBlast.
📖 API docs
XML documentation is included with the package and covers all public types:
ServiceCollectionExtensions.AddAzureBlast(...)(options-based)AzureBlastRegistration.UseAzureBlast(...)(fluent builder)AzureBlastFactory(script/no-DI helpers)IMssqlDatabase,IAzureServiceBus,IAzureKeyVault,IAzureTableStorage,IAzureResourceClient, etc.
📝 Notes
- Credentials: If you don’t pass a
TokenCredential,DefaultAzureCredentialis used. - Key Vault: The client is initialized during registration via
InitializeKeyVaultAsync(vaultUrl)so it’s ready to use. - Table Storage: You can set a default table during registration and change it later with
SetTable(...).
🔧 Minimal quick-start (Service Bus only)
using AzureBlast;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddAzureBlast(o =>
{
o.ServiceBusConnectionString = "<sb-connection-string>";
o.ServiceBusQueueName = "queue1";
});
var sp = services.BuildServiceProvider();
var bus = sp.GetRequiredService<AzureBlast.Interfaces.IAzureServiceBus>();
await bus.SendMessageAsync("""{ "hello": "world" }""");
🤖 AI assistants
This assembly carries the Blast.PrimaryFacade convention: an
[AssemblyMetadata("Blast.PrimaryFacade", "...")] attribute names the
canonical front-door type(s) of the package, so AI helpers (e.g.
TaskBlaster's script assistant) can identify the entry points without
scanning every public type.
For AzureBlast the front doors are:
| Type | Purpose |
|---|---|
AzureBlast.MssqlDatabase |
Azure SQL operations: Setup, SetupAsync, query helpers. |
AzureBlast.AzureServiceBus |
Service Bus producer / consumer. |
AzureBlast.AzureTableStorage |
Table Storage entity CRUD. |
AzureBlast.AzureKeyVault |
Key Vault secret access. |
Read it back from a loaded assembly via reflection:
var facade = typeof(AzureBlast.MssqlDatabase).Assembly
.GetCustomAttributes<AssemblyMetadataAttribute>()
.FirstOrDefault(a => a.Key == "Blast.PrimaryFacade")?.Value;
The value is a hint for tooling; consumers don't need to read it.
| 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
- Azure.Data.Tables (>= 12.11.0)
- Azure.Messaging.ServiceBus (>= 7.20.1)
- Azure.ResourceManager (>= 1.14.0)
- Azure.Security.KeyVault.Secrets (>= 4.10.0)
- Microsoft.Data.SqlClient (>= 7.0.0)
- Serilog (>= 4.3.1)
- Serilog.Extensions.Hosting (>= 10.0.0)
- Serilog.Extensions.Logging (>= 10.0.0)
- Serilog.Sinks.Console (>= 6.1.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.