Table of Contents

View Models

Blazing.Mvvm provides base classes and conventions that let Blazor components work with ViewModels in a predictable MVVM style.

Available base classes

Use the base class that matches your ViewModel needs:

Lifecycle methods

The ViewModel base classes mirror common ComponentBase lifecycle hooks:

  • OnInitialized
  • OnInitializedAsync
  • OnParametersSet
  • OnParametersSetAsync
  • OnAfterRender
  • OnAfterRenderAsync
  • ShouldRender

This lets component lifecycle flow into the ViewModel without custom plumbing in every page.

Disposal behavior

Since v3.2.1, all ViewModel base classes implement IDisposable. When a ViewModel is disposed, it automatically unsubscribes from all IAsyncRelayCommand PropertyChanged events. This matters most for commands with AllowConcurrentExecutions set to false, where the framework monitors the command's IsRunning property to trigger UI updates. Without cleanup, those subscriptions leak.

Automatic disposal gives you:

  • Memory leak prevention: command event subscriptions are cleaned up without manual tracking
  • Simpler ViewModels: no need to track and unsubscribe from command events yourself
  • A consistent pattern: all ViewModels follow the standard .NET dispose pattern
  • Efficient garbage collection: commands and ViewModels are released promptly

If a derived ViewModel needs to release additional resources, override Dispose(bool disposing):

[ViewModelDefinition(Lifetime = ServiceLifetime.Scoped)]
public sealed partial class MyViewModel : ViewModelBase
{
    private readonly CancellationTokenSource _cancellationTokenSource = new();

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            _cancellationTokenSource.Cancel();
            _cancellationTokenSource.Dispose();
        }

        base.Dispose(disposing);
    }
}
Warning

If you previously implemented public void Dispose() yourself, change that to protected override void Dispose(bool disposing) so the base class can keep its cleanup behavior.

Service registration

ViewModels are registered as transient services by default. Use ViewModelDefinition to choose another lifetime:

[ViewModelDefinition(Lifetime = ServiceLifetime.Scoped)]
public partial class FetchDataViewModel : ViewModelBase
{
    // ViewModel code
}

Then inherit your component from the matching MVVM base type:

@page "/fetchdata"
@inherits MvvmComponentBase<FetchDataViewModel>

Register with interfaces or abstract types

Use the generic ViewModelDefinition attribute when you want the ViewModel resolved through an abstraction:

[ViewModelDefinition<IFetchDataViewModel>]
public partial class FetchDataViewModel : ViewModelBase, IFetchDataViewModel
{
    // ViewModel code
}

The component can then depend on that abstraction:

@page "/fetchdata"
@inherits MvvmComponentBase<IFetchDataViewModel>

Register keyed ViewModels

Use a key when you need explicit string-based lookup:

[ViewModelDefinition(Key = "FetchDataViewModel")]
public partial class FetchDataViewModel : ViewModelBase
{
    // ViewModel code
}

Reference the key on the component with ViewModelKey:

@page "/fetchdata"
@attribute [ViewModelKey("FetchDataViewModel")]
@inherits MvvmComponentBase<FetchDataViewModel>

When to use each component base type