BladeState 1.0.2
dotnet add package BladeState --version 1.0.2
NuGet\Install-Package BladeState -Version 1.0.2
<PackageReference Include="BladeState" Version="1.0.2" />
<PackageVersion Include="BladeState" Version="1.0.2" />
<PackageReference Include="BladeState" />
paket add BladeState --version 1.0.2
#r "nuget: BladeState, 1.0.2"
#:package BladeState@1.0.2
#addin nuget:?package=BladeState&version=1.0.2
#tool nuget:?package=BladeState&version=1.0.2
BladeState
BladeState is a lightweight server-side dependency injection state persistence library for .NET applications.
It provides dependency-injected storage for persisting state across requests without relying on HttpContext.Session
.
β¨ Features
- π Server-side storage abstraction
- β‘ Easy integration with Dependency Injection
- π Works across Razor & Blazor server applications
- π§ Extensible design for custom providers (e.g. Redis, SQL, Memory Cache)
π Installation
Install via NuGet:
dotnet add package BladeState
π Providers
BladeState includes multiple built-in providers for persisting state:
1. Memory Cache Provider (MemoryCacheBladeStateProvider<T>
) β‘
Stores state in in-memory cache for the lifetime of the application.
using BladeState;
using BladeState.Models;
using BladeState.Providers;
builder.Services.AddBladeState<MyState, MemoryCacheBladeStateProvider<MyState>>();
2. SQL Provider (SqlBladeStateProvider<T>
) π
The SQL provider stores state in a relational database table using JSON serialization.
Example schema
CREATE TABLE BladeState (
InstanceId NVARCHAR(256) PRIMARY KEY,
[Data] NVARCHAR(MAX) NOT NULL
);
Registration
using Microsoft.Data.SqlClient;
using BladeState;
using BladeState.Models;
using BladeState.Providers;
builder.Services.AddBladeState<MyState, SqlBladeStateProvider<MyState>>(
() => new SqlConnection("Server=localhost;Database=BladeStateDb;User Id=yourUserId;Password=YourStrong(!)Password;TrustServerCertificate=True;"))
(
new BladeStateProfile
{
InstanceName = "MyBladeStateTable"
EncryptionKey = "my-crypto-key"
}
);
How it works
- Uses a simple key/value table (
InstanceId
,Data
). - JSON serialization handled automatically.
3. Redis Provider (RedisBladeStateProvider<T>
) π₯
Stores state in Redis using StackExchange.Redis
.
Registration
using BladeState.Providers;
using StackExchange.Redis;
builder.Services.AddSingleton<IConnectionMultiplexer>(
ConnectionMultiplexer.Connect("localhost")
);
builder.Services.AddBladeState<MyState, RedisBladeStateProvider<MyState>>(
new BladeStateProfile
{
InstanceName = "MyAppUsingRedis" //If InstanceName is not provided the value will be 'BladeState'
}
);
Notes
- Stores JSON under a Redis key formatted like
{BladeStateProfile.InstanceName}-{BladeStateProfile.InstanceId}
. - Fast, distributed, great for scale-out.
4. EF Core Provider (EfCoreBladeStateProvider<T>
) π’
Uses an Entity Framework DbContext
to persist state directly in your model.
Registration
using BladeState;
using BladeState.Models;
using BladeState.Providers;
using Microsoft.EntityFrameworkCore;
builder.Services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer("Server=localhost;Database=BladeStateDb;User Id=sa;Password=YourStrong(!)Password;TrustServerCertificate=True;"));
builder.Services.AddBladeState<MyState, EfCoreBladeStateProvider<MyState>>(
new BladeStateProfile
{
InstanceName = "MyEfCoreState",
EncryptionKey = "my-crypto-key"
}
);
Notes
- Assumes
T
maps directly to a table via EF Core. - Uses normal
DbContext.SaveChangesAsync()
semantics. - Best for when you want strongly typed schema vs JSON.
βοΈ Provider Comparison
Provider | Best For | Pros | Cons |
---|---|---|---|
Memory Cache | Performance and application level processing | Simple, next to no overhead, fast | Requires custom handling for persistence if necessary |
SQL | Simple persistence in relational DB | Works out of the box, JSON storage | Tied to SQL dialect, less efficient than Redis |
Redis | High-performance distributed cache | Fast, scalable, great for web farms | Requires Redis infrastructure, persistence optional |
EF Core | Strongly-typed relational models | Uses your existing EF models, schema-first | More overhead, requires migrations |
π§© Simple Service Collection Wire-up
Usage:
builder.Services.AddBladeState<MyState, SqlBladeStateProvider<MyState>>();
π Example: Consuming State
public class MyService
{
private readonly BladeStateProvider<MyState> _stateProvider;
public MyService(BladeStateProvider<MyState> stateProvider)
{
_stateProvider = stateProvider;
}
public async Task DoWorkAsync()
{
var state = await _stateProvider.LoadStateAsync();
state.Counter++;
await _stateProvider.SaveStateAsync(state);
}
}
πΏ Drive BladeState with BladeStateProfile!
var profile = new BladeStateProfile
{
InstanceId = string.Empty,
InstanceName = "MyApplicationState",
InstanceTimeout = TimeSpan.FromMinutes(120),
SaveOnInstanceTimeout = true,
AutoEncrypt = true,
EncryptionKey = "my-crypto-key"
}
βοΈ Example: Binding Profile from appsettings.json
You can configure profiles from appsettings.json and register them directly with a couple simple steps:
- Add the following structure to your appsettings.json file
{
"BladeState": {
"Profile": {
"InstanceId": "MyApplicationState",
"EncryptionKey": "my-crypto-key"
}
}
}
- Get the section and pass the BladeStateProfile to the 'AddBladeState();' extension method in your Program.cs
using BladeState;
using BladeState.Models;
using BladeState.Providers;
var profile = builder.Configuration.GetSection("BladeState:Profile").Get<BladeStateProfile>();
builder.Services.AddBladeState<MyAppState, SqlBladeStateProvider<MyAppState>>(profile);
βπͺ½ Built-in Encryption
BladeState automatically encrypts persisted state data using AES encryption.
Enabled by default β you donβt need to do anything.
Encryption key β if not provided, BladeState will generate one automatically, simplifying encryption and decryption without explicit wire-up.
You may also supply your own key by configuring a BladeStateProfile
, example below:
var profile = new BladeStateProfile
{
AutoEncrypt = true, // enable encryption
EncryptionKey = "my-crypto-key" // optional custom key
};
builder.Services.AddBladeState<MyAppState, SqlBladeStateProvider<MyAppState>>(profile);
Optionally (and NOT to be used for Production Environments - the universe frowns heavily upon that action π): You may turn off encryption β you can explicitly disable it via AutoEncrypt in your profile:
This is not necessary even when wiring up your own BladeStateProvider. The Decrypt/Encrypt State methods should be explicitly used.
var profile = new BladeStateProfile
{
AutoEncrypt = false // disables automatic crypto transforms in the 'out of the box' providers
};
builder.Services.AddBladeState<MyAppState, RedisBladeStateProvider<MyAppState>>(profile);
βBuilt-In Events
When a provider method is called an event will be raised to be handled by consuming components and services. This is useful for reliable UI updates.
// inject the provider
[Inject]
required public MemoryCacheBladeStateProvider<MyState> Provider { get; set; }
// add an event handler (anonymously)
Provider.OnStateChange += (sender, args) =>
{
// get updated state if need be
var state = args.State;
// do something
Console.WriteLine($"State changed: {args.EventType} for {args.InstanceId}! There are now {state.Items.Count} items!");
};
// add a custom handler
Provider.OnStateChange += MyCustomEventHandler;
π License
This project is licensed under the MIT License - see the LICENSE file for details.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net9.0
- Microsoft.EntityFrameworkCore (>= 9.0.8)
- StackExchange.Redis (>= 2.9.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.