Dotnet Stars Discord workflow nuget nuget Issues Open Forks License Twitter

Twitter Twitter

Blazor-State

TimeWarp Logo

Blazor-State is a State Management architecture utilizing the MediatR pipeline.

If you are familiar with MediatR 1, Redux 2, or the Command Pattern 3 you will feel right at home. All of the behaviors are written as middleware to the MediatR pipeline.

Please see the GitHub Site for source and filing of issues.

Installation

You can see the latest NuGet packages from the official TimeWarp NuGet page.

  • Blazor-State nuget
dotnet add package Blazor-State

Getting Started

If you are just beginning with Blazor then I recommend you start at the dotnet blazor site.

If you already know a bit about Blazor then I recommend the tutorial

Tutorial

If you would like a basic step by step on adding blazor-state to the blazorwasm --hosted template then follow this tutorial.

TimeWarp Architecture Template

To create a distributed application that utilizes blazor-state see the timewarp-architecture template.

The Blazor-State Architecture

Store 1..* State

Blazor-State implements a single Store with a collection of States.

To access a state you can either inherit from the BlazorStateComponent and use

Store.GetState<YourState>()

or move the GetState functionality into your component

  protected T GetState<T>()
  {
    Type stateType = typeof(T);
    Subscriptions.Add(stateType, this);
    return Store.GetState<T>();
  }

Pipeline

Blazor-State utilizes the MediatR pipeline which allows for middleware integration by registering an interface with the dependency injection container 4. Blazor-State provides the extension method 5 , AddBlazorState, which registers behaviors on the pipeline.

The interfaces available to extend the Pipeline are:

  • IPipelineBehavior
  • IRequestPreProcessor
  • IRequestPostProcessor
  • IStreamPipelineBehavior

You can add functionality to the pipeline by implementing and registering one of these interfaces. See the timewarp-architecture EventStreamBehavior for an example.

Behaviors/Middleware

Blazor-State ships with the following default middleware.

CloneStateBehavior

To ensure your application is in a known good state the CloneStateBehavior creates a clone of the State prior to processing the Action. If any exception occurs during the processing of the Action the state is rolled back.

RenderSubscriptionsPostProcessor

When a component accesses State a subscription is added. The RenderSubscriptionsPostProcessor will iterate over these subscriptions and re-render those components. So you don't have to worry about where to call StateHasChanged.

JavaScript Interop

Blazor-State uses the same "Command Pattern" for JavaScript interoperability. The JavaScript creates a request and dispatches it to Blazor where it is added to the pipeline. Handlers on the Blazor side can callback to the JavaScript side if needed.

ReduxDevToolsPostProcessor

Note

Disabled by default. This should be disabled in production.

One of the nice features of redux is the developer tools 6. This processor implements the integration of these developer tools.

Terminology

The pattern used by Blazor-State and MediatR has been around for many years and goes by different names. We list various related terms here and Bold indicates the term used in Blazor-State.

Signals/Actions/Requests/Commands/

In Redux they call them "Action".
In UML they are "Signal".
In Command Pattern they are "Command"
In MediatR they are Request In Blazor-State we call them Actions when they are handled on the Client and Requests if they handled on the Server.

Reducer/Handler/Executor

This is the code that processes the Request/Action and returns the Response.

In Redux they call them "Reducer". In Command Pattern we call them "Executor".
In MediatR they are Handler.
In Blazor-State we call them Handler.

Feature

A Feature is the collection of the code needed to implement a particular Vertical Slice of the application.

On the server side we use the same architecture, where the Features contain Endpoint, Handler, Request, Response, etc... Each endpoint maps the HTTP Request to the Request object and then sends the Request on to the mediator pipeline. The Handler acts on the Request and returns a Response.

Server side follows the Request in Response out pattern.

A Feature Folder on the client side will contain an Action and the Handler and any corresponding files needed for this feature. The Handler acts on the Action and updates the corresponding State.

Client side follows the Action in new State out pattern.

PureFunctions vs NonPureFunctions

Blazor-State does not distinguish between these. As they are processed via the pipeline the same. Thus, async calls to fetch data, send emails, or just update local state are implemented in the same manner. Although the developer should be aware that Handlers have side effects and if the developer chose they could mark the Requests as such. For example IActionWithSideEffect

Acknowledgements

Jimmy Bogard (MediatR). Jimmy is an amazing developer and knowledge sharer.
Through his course at 11x Engieering, his many blog posts on Los Techies and now JimmyBogard.com, I have learned a great amount.

Peter Morris and I have been friends for many years. He is an amazing developer and a person who has taught me a great deal. Not surprisingly, Pete and I think a lot alike. We both, independently, started working on our own State Management components. Although I started first. :P Pete's component attempts to solve most of the same problems. Blazor-State draws on the strengths of a proven pipeline in MediatR where Fluxor implements its own middleware.
If Blazor-State does not meet your needs be sure to checkout Fluxor.

UnLicense

The Unlicense

Contributing

Time is of the essence. Before developing a Pull Request I recommend opening an discussion.

Please feel free to make suggestions and help out with the documentation. Please refer to Markdown for how to write markdown files.

Footnotes:


  1. https://github.com/jbogard/MediatR↩

  2. https://redux.js.org/↩

  3. https://en.wikipedia.org/wiki/Command_pattern↩

  4. https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection↩

  5. https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods↩

  6. https://github.com/reduxjs/redux-devtools↩

  • Improve this Doc
In This Article
Back to top Generated by DocFX