BladeState 1.0.2

dotnet add package BladeState --version 1.0.2
                    
NuGet\Install-Package BladeState -Version 1.0.2
                    
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="BladeState" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BladeState" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="BladeState" />
                    
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 BladeState --version 1.0.2
                    
#r "nuget: BladeState, 1.0.2"
                    
#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 BladeState@1.0.2
                    
#: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=BladeState&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=BladeState&version=1.0.2
                    
Install as a Cake Tool

BladeState

NuGet Version NuGet Downloads License

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:

  1. Add the following structure to your appsettings.json file

{
  "BladeState": {
    "Profile": {
      "InstanceId": "MyApplicationState",
      "EncryptionKey": "my-crypto-key"
    }
  }
}


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

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
1.0.2 106 9/11/2025
1.0.1 109 9/10/2025
1.0.0 113 9/8/2025