A simple Flux architecture implementation for .NET applications with minimal dependencies and boilerplate code. Particularly useful for Blazor applications.
- ๐ชถ Lightweight Flux implementation
- โก First-class Blazor support
- ๐ฆ Minimal dependencies
- ๐ Type-safe state management
- ๐ Easy integration with dependency injection
- ๐ Built-in middleware support
Install via NuGet:
dotnet add package SimpleFlux.NET- Define your state:
public sealed record ExampleState : AbstractFluxState
{
public int Counter { get; init; }
public WeatherForecast[]? Forecasts { get; init; }
}- Create actions:
public sealed record IncrementCounterButtonClickedAction : IFluxAction { }- Create a reducer:
public sealed class IncrementCounterReducer : IFluxReducer<ExampleState, IncrementCounterButtonClickedAction>
{
public ExampleState Reduce(IncrementCounterButtonClickedAction action, ExampleState currentState) => currentState with
{
Counter = currentState.Counter + 1
};
}- Set up in your Blazor application:
builder.Services.AddFluxStateManagement(flux =>
{
flux.ConfigureStateContainer<ExampleState>(state =>
{
state.HandleAction<IncrementCounterButtonClickedAction>(action =>
action.UseReducer<IncrementCounterReducer>());
// You can also define inline reducers
state.HandleAction<SomeOtherAction>(action =>
{
action.UseReducer(static (action, state) => state with
{
// Update state here
});
});
// Or use middleware for side effects
state.HandleAction<LoadDataAction>(action =>
action.UseMiddleware<LoadDataMiddleware>());
});
});- Use in components:
@page "/counter"
@using SimpleFluxDotNet.Abstractions
@inherits FluxComponent<ExampleState>
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @State.Current.Counter</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private Task IncrementCount() =>
State.DispatchAsync(new IncrementCounterButtonClickedAction());
}SimpleFluxDotNet- Core library with Flux implementationSimpleFluxDotNet.Example- Example Blazor application showcasing usageSimpleFluxDotNet.Tests- Unit tests
- State: Immutable state container that holds your application's data
- Actions: Plain objects describing what happened
- Reducers: Pure functions that specify how the state changes in response to actions
- Store: Holds the state and handles dispatching of actions
- Middleware: Intercepts actions for side effects, logging, etc.
The base interface for all actions in your application.
Base class for your application's state objects.
Base component class that provides access to state and dispatch capabilities.
Interface for implementing reducers that handle specific action types. Reducers are pure functions that take the current state and an action, and return a new state.
public interface IFluxReducer<TState, TAction> where TState : AbstractFluxState where TAction : IFluxAction
{
TState Reduce(TAction action, TState currentState);
}Interface for implementing middleware that handles side effects for specific action types. Middleware can perform async operations and dispatch additional actions.
public interface IFluxMiddleware<TState, TAction> where TState : AbstractFluxState where TAction : IFluxAction
{
Task HandleAsync(TAction action, TState currentState, IFluxDispatcher dispatcher);
}Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.