Browser based storage.
$ dotnet add package Cirreum.Storage.BrowserCore abstractions and contracts for browser storage in Blazor applications. This package provides the interfaces, event arguments, and configuration types used by storage implementations.
Note: This package contains only the contracts and abstractions.
This package provides the foundational types for building storage implementations:
IAsyncStorageService - Core storage operations interfaceILocalStorageService - Marker interface for localStorage implementationsISessionStorageService - Marker interface for sessionStorage implementationsIStorageSerializer - Serialization abstraction for custom serializersStorageChangedEventArgs - Event data for storage changes (after operation)StorageChangingEventArgs - Event data for storage changes (before operation, cancellable)StorageOptions - Configuration options including JsonSerializerOptionsdotnet add package Cirreum.Storage.BrowserThis package is typically referenced by:
Cirreum.Blazor.Components) that provide concrete implementationsReference this package to work with storage abstractions:
using Cirreum.Storage;
public class UserService
{
private readonly ILocalStorageService _storage;
public UserService(ILocalStorageService storage)
{
_storage = storage;
}
public async Task SaveUserAsync(User user)
{
await _storage.SetItemAsync("current-user", user);
}
}Install both this package and an implementation package (e.g., Cirreum.Storage.Browser):
dotnet add package Cirreum.Storage.Browser
dotnet add package Cirreum.Blazor.ComponentsThen register the services:
// Program.cs
using Cirreum.Storage;
builder.Services.AddLocalStorage();
builder.Services.AddSessionStorage();Core interface for storage operations:
public interface IAsyncStorageService
{
// Initialization
ValueTask InitializeAsync();
// Basic Operations
Task SetItemAsync<T>(string key, T data);
Task SetItemAsync<T>(string key, T data, JsonTypeInfo<T> typeInfo);
Task SetItemAsStringAsync(string key, string data);
Task<T?> GetItemAsync<T>(string key);
Task<T?> GetItemAsync<T>(string key, JsonTypeInfo<T> typeInfo);
Task<string?> GetItemAsStringAsync(string key);
Task RemoveItemAsync(string key);
Task RemoveItemsAsync(IEnumerable<string> keys);
Task ClearAsync();
// Key Management
Task<bool> ContainsKeyAsync(string key);
Task<IEnumerable<string>> KeysAsync();
Task<string?> KeyAsync(int index);
Task<int> LengthAsync();
// Events
event EventHandler<StorageChangingEventArgs> Changing;
event EventHandler<StorageChangedEventArgs> Changed;
}Marker interface for localStorage implementations:
public interface ILocalStorageService : IAsyncStorageService { }Marker interface for sessionStorage implementations:
public interface ISessionStorageService : IAsyncStorageService { }Interface for custom serialization implementations:
public interface IStorageSerializer
{
string Serialize<T>(T obj);
string Serialize<T>(T obj, JsonTypeInfo<T> typeInfo);
T? Deserialize<T>(string text);
T? Deserialize<T>(string text, JsonTypeInfo<T> typeInfo);
}Provides data for the Changed event (fired after a storage operation completes):
public class StorageChangedEventArgs
{
public string Key { get; set; } // The storage key that changed
public object? OldValue { get; set; } // Previous value (null if newly created)
public object? NewValue { get; set; } // New value (null if removed)
}Provides data for the Changing event (fired before a storage operation executes):
public class StorageChangingEventArgs : StorageChangedEventArgs
{
public bool Cancel { get; set; } // Set to true to cancel the operation
}Example usage:
storage.Changing += (sender, e) =>
{
if (e.Key == "protected-key")
{
e.Cancel = true; // Prevent the change
}
};
storage.Changed += (sender, e) =>
{
Console.WriteLine($"Key '{e.Key}' changed from {e.OldValue} to {e.NewValue}");
};Configuration options for storage implementations:
public class StorageOptions
{
public JsonSerializerOptions JsonSerializerOptions { get; set; }
}Configure in your application:
builder.Services.Configure<StorageOptions>(options =>
{
options.JsonSerializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
});To create your own storage implementation:
IAsyncStorageService (or ILocalStorageService/ISessionStorageService)IStorageSerializer for custom serializationpublic class CustomStorageService : ILocalStorageService
{
public ValueTask InitializeAsync() { /* ... */ }
public Task SetItemAsync<T>(string key, T data) { /* ... */ }
// ... implement other methods
}
// Register
builder.Services.AddSingleton<ILocalStorageService, CustomStorageService>();Cirreum Foundation Framework - Layered simplicity for modern .NET