Blaztore 1.1.3
See the version list below for details.
dotnet add package Blaztore --version 1.1.3
NuGet\Install-Package Blaztore -Version 1.1.3
<PackageReference Include="Blaztore" Version="1.1.3" />
paket add Blaztore --version 1.1.3
#r "nuget: Blaztore, 1.1.3"
// Install Blaztore as a Cake Addin #addin nuget:?package=Blaztore&version=1.1.3 // Install Blaztore as a Cake Tool #tool nuget:?package=Blaztore&version=1.1.3
Blaztore
A simple and modest library to implement Flux/Redux pattern in .NET Blazor.
Introduction
If you are not familiar with the Flux/Redux model, have a look on the following nice resources:
You can find diagrams here to help you understand.
Goal 🎯
Blazor does not contain a native Flux/Redux or MVU api internally.
The objective of this library is to provide a very simple and minimalist api to implement a Flux/Redux architecture.
This repository is largely inspired by the following existing repositories:
If you are not satisfied by this library, don't hesitate to check them out, they are great.
Advantages 💪
Compared to the listed existing libraries, Blaztore has the following advantages:
- ✅ Focused on immutability for every concepts (State, Action, ...)
- ✅ Never force you to inherit from a base class or a base record. Every concepts are based on interfaces. It allows you to structure your code as you like (multiple handling, file structure, ...)
- ✅ Use the underlying MediatR library to dispatch actions. It is highly extendable and allows you to easily implement pipeline or preprocessing to add loggers, retry pattern, ...
- ✅ Use the Flux/Redux terminology and not a custom one.
- ✅ Enable to store multiple instances of the same state type, identified by a unique id.
Installation 💻
You can download the latest release NuGet packages from the official Blaztor nuget pages.
Getting started 🏁
You can find below examples to illustrate how to implement concepts with Blazstore.
State
A state represents the data of a particular component. In .NET record is largely recommended for state immutability.
public record TaskCreationState(bool IsAddingTask, string? NewTaskDescription) : IState
{
// Mandatory static factory method to create the initial state.
public static TaskCreationState Initialize() => new(false, null);
}
Action
Actions are messages that can represent a command to mutate the system or an event that happened in the system.
You must implement IAction<TState>
to explicitly define for which state is this action.
public record StartAddingNewTask : IAction<TaskCreationState>;
public record DefineNewDescription(string NewDescription) : IAction<TaskCreationState>;
public record TaskListLoaded(IReadOnlyCollection<TaskListItem> Payload) : IAction<TaskListState>;
Get state reference and dispatch actions from a component
A base component StateComponent
is provided to easily access the Dispatch<TAction>(TAction action)
and GetState<TState>()
method.
@inherits Blaztore.Components.StateComponent
You can dispatch actions directly from the html, you have no more code-behind !
<button onclick="@(() => Dispatch(new StartAddingNewTask()))">
New task
</button>
@code {
private TaskCreationState State => GetState<TaskCreationState>();
protected override Task OnAfterInitialRenderAsync() =>
Dispatch(new TaskCreationState.Load());
}
Reducer
A pure reducer is a function that execute an action on a state, returning a new state. Theoretically, it should not have any dependencies and generates no side effects.
public record StartAddingNewTaskReducer(IStore Store)
: IPureReducer<TaskCreationState, StartAddingNewTask>
{
public TaskCreationState Reduce(TaskCreationState state, StartAddingNewTask action) =>
state with
{
IsAddingTask = true
};
}
You can organize you reducers as you prefer: a reducer for each action or a single reducer for all your actions.
public record TaskCreationStateReducer(IStore Store)
: IPureReducer<TaskCreationState, StartAddingNewTask>,
IPureReducer<TaskCreationState, EndAddingNewTask>
{
public TaskCreationState Reduce(TaskCreationState state, StartAddingNewTask action) =>
state with
{
IsAddingTask = true
};
public TaskCreationState Reduce(TaskCreationState state, EndAddingNewTask action) =>
state with
{
NewTaskDescription = null,
IsAddingTask = false
};
}
Effect
An effect allows you to execute side effects on external system and dispatching new actions.
public record ExecuteTaskCreationEffect(
IStore Store,
ITodoListApi Api,
IActionDispatcher ActionDispatcher
) : IEffect<TaskCreationState, ExecuteTaskCreation>
{
public async Task Effect(TaskCreationState state, ExecuteTaskCreation action)
{
if (string.IsNullOrWhiteSpace(state.NewTaskDescription))
{
return;
}
await Api.Create(Guid.NewGuid(), state.NewTaskDescription);
await ActionDispatcher.Dispatch(new EndAddingNewTask());
await ActionDispatcher.Dispatch(new TodoListState.Load());
}
}
To see full examples go here or here.
Examples
You can find an example app in Blazor Wasm with Blaztor implementation here.
Release notes
v1.1.3: minor fixes
- fix: missing dependency injection configuration for IActionEventDispatcher
- fix: IEffect was retrieving wrong state (not scoped when action was scoped)
v1.1.n: minor fixes
- doc: add readme and assets
v1: initial version
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net7.0
- MediatR (>= 12.1.1)
- Microsoft.AspNetCore.Components (>= 7.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.