Zonit.Extensions.Projects 10.0.0-preview.19

This is a prerelease version of Zonit.Extensions.Projects.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Zonit.Extensions.Projects --version 10.0.0-preview.19
                    
NuGet\Install-Package Zonit.Extensions.Projects -Version 10.0.0-preview.19
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Zonit.Extensions.Projects" Version="10.0.0-preview.19" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Zonit.Extensions.Projects" Version="10.0.0-preview.19" />
                    
Directory.Packages.props
<PackageReference Include="Zonit.Extensions.Projects" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Zonit.Extensions.Projects --version 10.0.0-preview.19
                    
#r "nuget: Zonit.Extensions.Projects, 10.0.0-preview.19"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Zonit.Extensions.Projects@10.0.0-preview.19
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Zonit.Extensions.Projects&version=10.0.0-preview.19&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Zonit.Extensions.Projects&version=10.0.0-preview.19&prerelease
                    
Install as a Cake Tool

Zonit.Extensions.Projects

Per-scope "which project is the user working in?" context. Framework-agnostic — no HttpContext, no middleware here; the ASP.NET Core / Blazor wiring lives in Zonit.Extensions.Website.

NuGet Downloads

dotnet add package Zonit.Extensions.Projects

A catalog is a project. One value object, Project, two names: the services around it are called ICatalogProvider / ICatalogManager / CatalogModel. There is no separate catalog entity.

What you get

  • ICatalogProvider (read-only) — Project Project (Project.Empty when nothing is selected), ImmutableArray<Project> Visible, event Action? OnChange. Both members are cached snapshots, rebuilt when the manager changes.
  • ICatalogManager (write / raw models) — Initialize(StateModel), Task<StateModel> InitializeAsync(ct), Task<bool> SwitchProjectAsync(Guid, ct), plus CatalogModel? Catalog, IReadOnlyCollection<ProjectModel>? Projects, StateModel? State (null = this scope was never hydrated) and OnChange.
  • IProjectSource — the one contract your app implements.
  • AddProjectsExtension() — the package's only DI entry point. All registrations are scoped.

Setup

builder.Services.AddWebsite();                                   // already calls AddProjectsExtension()
builder.Services.AddScoped<IProjectSource, AppProjectSource>();  // AddScoped, never TryAdd

AddProjectsExtension() TryAdds an internal null source as a safety net, so registering yours with TryAddScoped loses to it and the app silently shows no project at all.

In a Zonit.Extensions.Website host, UseWebsite<TApp>(...) hydrates each authenticated request and <WebsiteHydrator /> carries the snapshot across the prerender → interactive boundary. Elsewhere, call InitializeAsync yourself when State is null.

Implementing the source

public interface IProjectSource
{
    // Never returns null — an empty CatalogModel means "nothing selected".
    Task<CatalogModel> InitializeAsync(CancellationToken cancellationToken = default);

    Task<IReadOnlyCollection<ProjectModel>?> GetProjectsAsync(CancellationToken cancellationToken = default);

    // null == no access. The switch is refused and the current project is kept.
    Task<CatalogModel?> SwitchProjectAsync(Guid projectId, CancellationToken cancellationToken = default);
}

InitializeAsync and GetProjectsAsync are invoked concurrently on the same instance, so do not share a DbContext between them. Scoping the query to the active organization is your job — inject IWorkspaceProvider from Zonit.Extensions.Organizations.

Reading and switching

@inject ICatalogProvider Catalog
@inject ICatalogManager Manager

@if (Catalog.Project.HasValue)          @* readonly struct — never test != null *@
{
    <h2>@Catalog.Project.Name</h2>
}

@foreach (var project in Catalog.Visible)
{
    <button @onclick="() => SwitchAsync(project.Id)">@project.Name</button>
}

@code {
    private async Task SwitchAsync(Guid id)
    {
        if (!await Manager.SwitchProjectAsync(id))
        {
            // Denied: nothing changed, no OnChange fired, the previous project is still active.
        }
    }
}

Malformed source rows degrade rather than throw: a row with Id == Guid.Empty is dropped from Visible, a blank name becomes Title.Empty, and a name over 60 graphemes is cut. Visible.Length can therefore be smaller than Projects.Count — join on Id, never by index.

The full guide, including the traps, ships inside the package and is installed into consuming repos at .zonit/extensions/projects/projects.md.

License

MIT.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Zonit.Extensions.Projects:

Package Downloads
Zonit.Extensions.Website

ASP.NET Core and Blazor web extensions providing base components (PageBase, PageEditBase, PageViewBase), navigation services, breadcrumbs management, toast notifications, cookie handling, and data protection utilities for building modern web applications.

Zonit.Services.Dashboard

Package Description

Zonit.Services.Manager

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.0.0-preview.20 0 8/10/2026
10.0.0-preview.19 0 8/10/2026
10.0.0-preview.18 29 8/9/2026
10.0.0-preview.17 34 8/9/2026
10.0.0-preview.16 34 8/9/2026
10.0.0-preview.15 46 8/7/2026
10.0.0-preview.14 42 8/6/2026
10.0.0-preview.13 49 8/6/2026
10.0.0-preview.12 42 8/6/2026
10.0.0-preview.11 69 8/4/2026
10.0.0-preview.10 58 8/3/2026
10.0.0-preview.9 69 5/16/2026
10.0.0-preview.6 77 5/15/2026
10.0.0-preview.2 70 5/12/2026
0.1.51 147 1/15/2026
0.1.50 506 11/18/2025
0.1.4 577 1/29/2025
0.1.3 228 6/13/2024
0.1.2 202 6/13/2024
0.1.1 203 6/13/2024
Loading failed