Nabs.Launchpad.Core.Context
10.0.210
Prefix Reserved
dotnet add package Nabs.Launchpad.Core.Context --version 10.0.210
NuGet\Install-Package Nabs.Launchpad.Core.Context -Version 10.0.210
<PackageReference Include="Nabs.Launchpad.Core.Context" Version="10.0.210" />
<PackageVersion Include="Nabs.Launchpad.Core.Context" Version="10.0.210" />
<PackageReference Include="Nabs.Launchpad.Core.Context" />
paket add Nabs.Launchpad.Core.Context --version 10.0.210
#r "nuget: Nabs.Launchpad.Core.Context, 10.0.210"
#:package Nabs.Launchpad.Core.Context@10.0.210
#addin nuget:?package=Nabs.Launchpad.Core.Context&version=10.0.210
#tool nuget:?package=Nabs.Launchpad.Core.Context&version=10.0.210
Nabs Launchpad Core Context Library
The Nabs Launchpad Core Context library provides essential context management classes for multi-tenant Blazor applications with Orleans integration. This library defines the core context objects for users, tenants, and portals, along with utilities for passing context through Orleans grain calls.
Key Features
- User Context Management: Track authenticated user information across the application
- Tenant Context Support: Multi-tenant application support with tenant-specific data
- Portal Configuration: Flexible portal configuration with navigation and branding
- Orleans Integration: Seamless context propagation through Orleans RequestContext
- Serialization Support: Orleans-compatible serialization attributes for distributed scenarios
- Theme Preferences: User-specific theme preferences (dark/light mode)
- Navigation Configuration: Type-safe navigation item definitions
Core Components
UserContext
Represents the authenticated user's context information including identity, preferences, and correlation tracking. Fully serializable for Orleans grain calls.
TenantContext
Provides tenant-specific context for multi-tenant applications.
PortalContext
Defines portal configuration including branding, navigation, authentication settings, and base paths.
NavigationItem
Represents a navigation menu item with path, display name, and icon configuration.
UserContextExtensions
Extension methods for accessing user context from Orleans grains through RequestContext.
Usage Examples
User Context
// Create user context from authentication
var userContext = new UserContext
{
IsAuthenticated = true,
ObjectId = "user-123",
DisplayName = "John Doe",
Email = "john.doe@example.com",
CorrelationId = Guid.NewGuid().ToString(),
PreferredTheme = "dark"
};
// Check authentication
if (userContext.IsAuthenticated)
{
Console.WriteLine($"Welcome, {userContext.DisplayName}");
}
// Use correlation ID for logging
logger.LogInformation("Request {CorrelationId} from {User}",
userContext.CorrelationId, userContext.Email);
Portal Context Configuration
// Configure portal settings
var portalContext = new PortalContext
{
PortalName = "admin-portal",
PortalDisplayName = "Administration Portal",
PortalBasePath = "/admin",
Copyright = "� 2024 My Company",
DisableAuth = false,
NavigationItems = new[]
{
new NavigationItem
{
Path = "/admin/dashboard",
DisplayValue = "Dashboard",
IconClass = "e-icons e-dashboard"
},
new NavigationItem
{
Path = "/admin/users",
DisplayValue = "Users",
IconClass = "e-icons e-users"
},
new NavigationItem
{
Path = "/admin/settings",
DisplayValue = "Settings",
IconClass = "e-icons e-settings"
}
}
};
// Use in application configuration
services.AddSingleton(portalContext);
Tenant Context
// Create tenant context
var tenantContext = new TenantContext
{
DisplayName = "Acme Corporation"
};
// Use in multi-tenant scenarios
services.AddScoped(_ => tenantContext);
Orleans Grain Integration
// In your grain interface
public interface IUserGrain : IGrainWithStringKey
{
Task<UserProfile> GetProfileAsync();
Task UpdatePreferencesAsync(string theme);
}
// In your grain implementation
public class UserGrain : Grain, IUserGrain
{
public Task<UserProfile> GetProfileAsync()
{
// Access user context from Orleans RequestContext
var userContext = this.GetUserContext();
if (userContext?.IsAuthenticated != true)
{
throw new UnauthorizedAccessException("User not authenticated");
}
// Use user context information
var profile = new UserProfile
{
UserId = userContext.ObjectId,
DisplayName = userContext.DisplayName,
Email = userContext.Email,
Theme = userContext.PreferredTheme
};
return Task.FromResult(profile);
}
public Task UpdatePreferencesAsync(string theme)
{
var userContext = this.GetUserContext();
// Log with correlation ID
logger.LogInformation(
"User {UserId} updated theme preference to {Theme} (Correlation: {CorrelationId})",
userContext?.ObjectId,
theme,
userContext?.CorrelationId);
// Update preferences logic...
return Task.CompletedTask;
}
}
Setting Orleans RequestContext (Client Side)
// In Blazor component or middleware
public class UserContextMiddleware
{
private readonly RequestDelegate _next;
public UserContextMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context, IUserService userService)
{
var user = context.User;
if (user.Identity?.IsAuthenticated == true)
{
var userContext = new UserContext
{
IsAuthenticated = true,
ObjectId = user.FindFirst("oid")?.Value ?? "",
DisplayName = user.Identity.Name ?? "",
Email = user.FindFirst(ClaimTypes.Email)?.Value ?? "",
CorrelationId = context.TraceIdentifier,
PreferredTheme = await userService.GetThemePreferenceAsync(user)
};
// Set in Orleans RequestContext for grain calls
RequestContext.Set("UserContext", userContext);
}
await _next(context);
}
}
Blazor Component Integration
@page "/profile"
@inject IClusterClient ClusterClient
@inject UserContext UserContext
<h3>User Profile</h3>
@if (UserContext.IsAuthenticated)
{
<div>
<p><strong>Name:</strong> @UserContext.DisplayName</p>
<p><strong>Email:</strong> @UserContext.Email</p>
<p><strong>Theme:</strong> @UserContext.PreferredTheme</p>
</div>
<button @onclick="UpdateTheme">Toggle Theme</button>
}
@code {
private async Task UpdateTheme()
{
var newTheme = UserContext.PreferredTheme == "dark" ? "light" : "dark";
// Call Orleans grain with automatic context propagation
var grain = ClusterClient.GetGrain<IUserGrain>(UserContext.ObjectId);
await grain.UpdatePreferencesAsync(newTheme);
}
}
Dynamic Navigation from Portal Context
@inject PortalContext PortalContext
<nav>
<h1>@PortalContext.PortalDisplayName</h1>
<ul>
@foreach (var navItem in PortalContext.NavigationItems)
{
<li>
<a href="@navItem.Path">
<i class="@navItem.IconClass"></i>
@navItem.DisplayValue
</a>
</li>
}
</ul>
<footer>@PortalContext.Copyright</footer>
</nav>
API Reference
UserContext
Properties
IsAuthenticated
public bool IsAuthenticated { get; init; }
Indicates whether the user is authenticated.
ObjectId
public string ObjectId { get; init; }
The unique identifier for the user (typically from identity provider).
DisplayName
public string DisplayName { get; init; }
The user's display name.
public string Email { get; init; }
The user's email address.
CorrelationId
public string CorrelationId { get; init; }
Correlation ID for tracking requests across services.
PreferredTheme
public string PreferredTheme { get; init; }
The user's preferred theme ("dark" or "light"). Defaults to "dark".
TenantContext
Properties
DisplayName
public string DisplayName { get; set; }
The display name of the tenant/organization.
PortalContext
Properties
PortalName
public string PortalName { get; set; }
A unique identifier name for the portal.
PortalDisplayName
public string PortalDisplayName { get; set; }
The human-readable display name for the portal.
PortalBasePath
public string PortalBasePath { get; set; }
The base path for all portal routes. Defaults to "/".
Copyright
public string Copyright { get; set; }
Copyright text displayed in the portal footer.
NavigationItems
public NavigationItem[] NavigationItems { get; set; }
Array of navigation menu items for the portal.
DisableAuth
public bool DisableAuth { get; set; }
Indicates whether authentication is disabled for the portal. Defaults to false.
NavigationItem
Properties
Path
public string Path { get; set; }
The navigation path/route.
DisplayValue
public string DisplayValue { get; set; }
The display text for the navigation item.
IconClass
public string IconClass { get; set; }
CSS class(es) for the navigation icon (e.g., "e-icons e-dashboard" for Syncfusion icons).
UserContextExtensions
Methods
GetUserContext
public static UserContext? GetUserContext(this IGrain grain)
Extension method to retrieve the UserContext from Orleans RequestContext within a grain.
Returns: The UserContext if available, otherwise null.
Usage:
public class MyGrain : Grain, IMyGrain
{
public Task DoSomethingAsync()
{
var userContext = this.GetUserContext();
if (userContext?.IsAuthenticated != true)
{
throw new UnauthorizedAccessException();
}
// ... rest of implementation
}
}
Orleans Serialization
The UserContext class is decorated with Orleans serialization attributes:
[Serializable]: Marks the class as serializable[GenerateSerializer]: Triggers Orleans source generator for optimized serialization[Alias]: Provides a stable type identifier for serialization versioning[Id(n)]: Marks properties for serialization with explicit ordering
This enables UserContext to be efficiently serialized when passed across Orleans grain boundaries.
Architecture Patterns
Multi-Tenant Support
Use TenantContext to scope data and operations to specific tenants in multi-tenant applications.
Correlation Tracking
Use the CorrelationId property in UserContext to track requests across distributed services for logging and debugging.
Portal Customization
Configure multiple PortalContext instances for different areas of your application (admin portal, user portal, etc.).
Theme Preferences
Store and retrieve user theme preferences through PreferredTheme for consistent UI experience.
Best Practices
- Set Context Early: Establish UserContext in middleware or authentication handlers
- Use Correlation IDs: Always populate CorrelationId for request tracking
- Immutable User Context: Use
initproperties to ensure context immutability - Validate Authentication: Always check
IsAuthenticatedbefore accessing user-specific data - Configure Portal Context at Startup: Register PortalContext as a singleton during application startup
- Use Extension Methods: Use
GetUserContext()extension method in grains for cleaner code - Handle Null Context: Always check for null when retrieving context in grains
Testing
Mocking User Context
[Fact]
public async Task GrainMethod_WithAuthenticatedUser_Success()
{
// Arrange
var mockContext = new UserContext
{
IsAuthenticated = true,
ObjectId = "test-user",
DisplayName = "Test User",
Email = "test@example.com",
CorrelationId = "test-correlation-id",
PreferredTheme = "dark"
};
RequestContext.Set("UserContext", mockContext);
var grain = GetTestGrain<IUserGrain>("test-user");
// Act
var result = await grain.GetProfileAsync();
// Assert
result.Should().NotBeNull();
result.DisplayName.Should().Be("Test User");
}
Dependencies
- Microsoft.Orleans.Core.Abstractions: For Orleans grain abstractions and RequestContext
Target Framework
- .NET 10
| Product | Versions 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. |
-
net10.0
- Microsoft.Orleans.Core.Abstractions (>= 9.2.1)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on Nabs.Launchpad.Core.Context:
| Package | Downloads |
|---|---|
|
Nabs.Launchpad.Ui.Shell
Package Description |
|
|
Nabs.Launchpad.Core.Silo
Package Description |
|
|
Nabs.Launchpad.Core.Portal
Package Description |
|
|
Nabs.Launchpad.Ui.Shell.Blazor.Sf
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 10.0.210 | 0 | 12/30/2025 | |
| 10.0.209 | 60 | 12/30/2025 | |
| 10.0.208 | 62 | 12/30/2025 | |
| 10.0.207 | 71 | 12/29/2025 | |
| 10.0.206 | 72 | 12/29/2025 | |
| 10.0.205 | 199 | 12/24/2025 | |
| 10.0.204 | 196 | 12/21/2025 | |
| 10.0.203 | 299 | 12/18/2025 | |
| 10.0.202 | 292 | 12/17/2025 | |
| 10.0.200 | 300 | 12/17/2025 | |
| 10.0.199 | 453 | 12/10/2025 | |
| 10.0.197 | 193 | 12/5/2025 | |
| 10.0.196 | 703 | 12/3/2025 | |
| 10.0.195 | 692 | 12/3/2025 | |
| 10.0.194 | 692 | 12/3/2025 | |
| 10.0.193 | 704 | 12/2/2025 | |
| 10.0.192 | 209 | 11/28/2025 | |
| 10.0.190 | 208 | 11/27/2025 | |
| 10.0.189 | 185 | 11/23/2025 | |
| 10.0.187 | 193 | 11/23/2025 | |
| 10.0.186 | 186 | 11/23/2025 | |
| 10.0.184 | 428 | 11/20/2025 | |
| 10.0.181-rc3 | 304 | 11/11/2025 | |
| 10.0.180 | 308 | 11/11/2025 | |
| 10.0.179-rc2 | 295 | 11/11/2025 | |
| 10.0.178-rc2 | 254 | 11/10/2025 | |
| 10.0.177-rc2 | 239 | 11/10/2025 | |
| 10.0.176-rc2 | 206 | 11/6/2025 | |
| 10.0.175-rc2 | 206 | 11/6/2025 | |
| 10.0.174-rc2 | 216 | 11/5/2025 | |
| 10.0.173-rc2 | 318 | 11/3/2025 | |
| 10.0.172-rc2 | 239 | 11/2/2025 | |
| 10.0.170-rc2 | 222 | 11/1/2025 | |
| 10.0.169-rc2 | 224 | 11/1/2025 | |
| 10.0.168-rc2 | 224 | 10/31/2025 | |
| 10.0.166-rc2 | 227 | 10/31/2025 | |
| 10.0.164-rc2 | 289 | 10/28/2025 | |
| 10.0.162-rc2 | 284 | 10/24/2025 | |
| 10.0.161 | 296 | 10/24/2025 | |
| 9.0.151 | 264 | 10/17/2025 | |
| 9.0.150 | 337 | 9/10/2025 | |
| 9.0.146 | 278 | 8/15/2025 | |
| 9.0.145 | 309 | 8/11/2025 | |
| 9.0.144 | 323 | 8/8/2025 | |
| 9.0.137 | 276 | 7/29/2025 | |
| 9.0.136 | 274 | 7/29/2025 | |
| 9.0.135 | 310 | 7/28/2025 | |
| 9.0.134 | 336 | 7/9/2025 | |
| 9.0.133 | 336 | 7/9/2025 | |
| 9.0.132 | 348 | 7/9/2025 | |
| 9.0.131 | 356 | 7/9/2025 | |
| 9.0.130 | 326 | 7/7/2025 |