Nabs.Launchpad.Core.Interfaces
10.0.189
Prefix Reserved
See the version list below for details.
dotnet add package Nabs.Launchpad.Core.Interfaces --version 10.0.189
NuGet\Install-Package Nabs.Launchpad.Core.Interfaces -Version 10.0.189
<PackageReference Include="Nabs.Launchpad.Core.Interfaces" Version="10.0.189" />
<PackageVersion Include="Nabs.Launchpad.Core.Interfaces" Version="10.0.189" />
<PackageReference Include="Nabs.Launchpad.Core.Interfaces" />
paket add Nabs.Launchpad.Core.Interfaces --version 10.0.189
#r "nuget: Nabs.Launchpad.Core.Interfaces, 10.0.189"
#:package Nabs.Launchpad.Core.Interfaces@10.0.189
#addin nuget:?package=Nabs.Launchpad.Core.Interfaces&version=10.0.189
#tool nuget:?package=Nabs.Launchpad.Core.Interfaces&version=10.0.189
Nabs Launchpad Core Interfaces Library
The Nabs Launchpad Core Interfaces library provides essential serialization configuration for Orleans-based distributed applications. This library enables JSON serialization for custom types and Ardalis.Result types in Orleans grain communication.
Key Features
- Orleans JSON Serialization: Configure JSON serialization for Orleans grain method parameters and return types
- Namespace-Based Configuration: Use namespace prefixes to control which types are JSON-serialized
- Ardalis.Result Support: Built-in JSON serialization support for Ardalis.Result types
- Flexible Type Selection: Customize serialization behavior based on type namespaces
- Dependency Injection Integration: Fluent API for registering serialization in service collection
Core Components
SerializationExtensions
Provides extension methods for configuring Orleans serialization with JSON support.
OrleansSerializationOptions
Configuration options specifying which namespace prefixes should use JSON serialization.
Usage Examples
Basic Serialization Setup
using Nabs.Launchpad.Core.Interfaces;
var builder = WebApplication.CreateBuilder(args);
// Configure Orleans serialization
var serializationOptions = new OrleansSerializationOptions();
serializationOptions.SupportedPrefixes.Add("MyApp.Models");
serializationOptions.SupportedPrefixes.Add("MyApp.Dtos");
builder.Services.AddOrleansSerialization(serializationOptions);
Multiple Namespace Prefixes
var serializationOptions = new OrleansSerializationOptions();
// Add multiple namespace prefixes
serializationOptions.SupportedPrefixes.Add("MyCompany.Domain");
serializationOptions.SupportedPrefixes.Add("MyCompany.Contracts");
serializationOptions.SupportedPrefixes.Add("MyCompany.ViewModels");
serializationOptions.SupportedPrefixes.Add("ThirdParty.Library");
builder.Services.AddOrleansSerialization(serializationOptions);
Silo Configuration
// In Orleans Silo configuration
var builder = Host.CreateDefaultBuilder(args);
builder.UseOrleans((context, siloBuilder) =>
{
siloBuilder.ConfigureServices(services =>
{
var serializationOptions = new OrleansSerializationOptions();
serializationOptions.SupportedPrefixes.Add("MyApp.Models");
services.AddOrleansSerialization(serializationOptions);
});
});
Client Configuration
// In Orleans Client configuration
var clientBuilder = new ClientBuilder();
clientBuilder.ConfigureServices(services =>
{
var serializationOptions = new OrleansSerializationOptions();
serializationOptions.SupportedPrefixes.Add("MyApp.Models");
services.AddOrleansSerialization(serializationOptions);
});
var client = clientBuilder.Build();
Using with Grain Interfaces
// Define your DTOs in a supported namespace
namespace MyApp.Models
{
public class UserProfile
{
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
}
// Grain interface using the DTO
public interface IUserGrain : IGrainWithStringKey
{
Task<Result<UserProfile>> GetProfileAsync();
Task<Result> UpdateProfileAsync(UserProfile profile);
}
// Grain implementation
public class UserGrain : Grain, IUserGrain
{
public Task<Result<UserProfile>> GetProfileAsync()
{
var profile = new UserProfile
{
Id = this.GetPrimaryKeyString(),
Name = "John Doe",
Email = "john@example.com"
};
return Task.FromResult(Result<UserProfile>.Success(profile));
}
public Task<Result> UpdateProfileAsync(UserProfile profile)
{
// Update logic
return Task.FromResult(Result.Success());
}
}
Ardalis.Result Integration (Automatic)
// Ardalis.Result types are automatically supported
public interface IOrderGrain : IGrainWithGuidKey
{
// Result types are automatically JSON-serialized
Task<Result<OrderDto>> GetOrderAsync();
Task<Result> ProcessOrderAsync(OrderDto order);
Task<Result<List<OrderDto>>> GetAllOrdersAsync();
}
// No additional configuration needed for Result types
var grain = client.GetGrain<IOrderGrain>(orderId);
var result = await grain.GetOrderAsync();
if (result.IsSuccess)
{
var order = result.Value;
Console.WriteLine($"Order: {order.Id}");
}
API Reference
SerializationExtensions
AddOrleansSerialization
public static IServiceCollection AddOrleansSerialization(
this IServiceCollection services,
OrleansSerializationOptions orleansSerializationOptions)
Configures Orleans JSON serialization for types matching the specified namespace prefixes.
Parameters:
services: The service collection to configureorleansSerializationOptions: Options specifying supported namespace prefixes
Returns: The service collection for method chaining
Automatically Supports:
- All types in namespaces starting with "Ardalis.Result"
- All types in namespaces matching configured prefixes
OrleansSerializationOptions
Properties
SupportedPrefixes
public List<string> SupportedPrefixes { get; }
List of namespace prefixes that should use JSON serialization. Types whose namespace starts with any of these prefixes will be JSON-serialized by Orleans.
How It Works
Serialization Selection
The library configures Orleans to use JSON serialization for specific types based on their namespace:
- Ardalis.Result Types: Always JSON-serialized (built-in support)
- Custom Types: JSON-serialized if their namespace starts with any configured prefix
- Other Types: Use Orleans' default serialization
Type Matching Logic
// Example internal logic
isSupported: type =>
{
var ns = type.Namespace!;
// Always support Ardalis.Result
if (ns.StartsWith("Ardalis.Result"))
return true;
// Check configured prefixes
foreach (var prefix in orleansSerializationOptions.SupportedPrefixes)
{
if (ns.StartsWith(prefix))
return true;
}
return false;
}
Best Practices
Namespace Organization
Organize your serializable types in dedicated namespaces:
// Good: Organized by purpose
MyApp.Models.Dtos // Data transfer objects
MyApp.Models.Commands // Command objects
MyApp.Models.Queries // Query objects
MyApp.Models.Events // Event objects
// Configure with:
serializationOptions.SupportedPrefixes.Add("MyApp.Models");
Avoid Overly Broad Prefixes
// Bad: Too broad, includes everything
serializationOptions.SupportedPrefixes.Add("MyApp");
// Good: Specific to serializable types
serializationOptions.SupportedPrefixes.Add("MyApp.Contracts");
serializationOptions.SupportedPrefixes.Add("MyApp.Shared.Models");
Consistent Configuration
Ensure both client and silo use the same serialization configuration:
// Shared configuration method
public static class SerializationConfig
{
public static OrleansSerializationOptions GetOptions()
{
var options = new OrleansSerializationOptions();
options.SupportedPrefixes.Add("MyApp.Contracts");
options.SupportedPrefixes.Add("MyApp.Shared");
return options;
}
}
// Use in both client and silo
services.AddOrleansSerialization(SerializationConfig.GetOptions());
Consider Performance
- JSON Serialization: Slower than Orleans' binary serialization but more flexible
- Use for DTOs: Apply to data transfer objects, commands, and queries
- Avoid for High-Frequency Calls: Consider binary serialization for performance-critical grain calls
Why JSON Serialization?
Advantages
- Flexibility: Easy to version and evolve types
- Debugging: Human-readable serialized data
- Interoperability: Can integrate with non-.NET systems
- Result Pattern: Perfect for Ardalis.Result types with complex success/error states
When to Use
- Data Transfer Objects (DTOs)
- API request/response models
- Configuration objects
- Types shared across different services
- Types that need frequent schema evolution
When to Use Binary Serialization
- High-frequency grain calls
- Large data structures
- Performance-critical paths
- Internal grain state (not crossing boundaries)
Troubleshooting
Serialization Errors
Issue: SerializationException when calling grain methods
Solution: Ensure the type's namespace is in SupportedPrefixes:
// If MyApp.Models.UserDto fails to serialize:
serializationOptions.SupportedPrefixes.Add("MyApp.Models");
Client/Silo Mismatch
Issue: Serialization works on silo but fails on client (or vice versa)
Solution: Ensure identical serialization configuration on both:
// Use shared configuration helper
var options = SerializationConfig.GetOptions();
services.AddOrleansSerialization(options);
Performance Issues
Issue: Grain calls are slow
Solution:
- Profile to identify if JSON serialization is the bottleneck
- Consider using Orleans' binary serialization for hot paths
- Use JSON serialization selectively for only necessary types
Integration with Other Libraries
With Nabs.Launchpad.Core.Context
// UserContext already uses Orleans serialization attributes
// But you can also use JSON serialization
serializationOptions.SupportedPrefixes.Add("Nabs.Launchpad.Core.Context");
With Nabs.Launchpad.Core.Dtos
// Enable JSON serialization for all DTOs
serializationOptions.SupportedPrefixes.Add("Nabs.Launchpad.Core.Dtos");
Testing
Testing Serialization Configuration
[Fact]
public void Serialization_ShouldSupportConfiguredNamespaces()
{
// Arrange
var services = new ServiceCollection();
var options = new OrleansSerializationOptions();
options.SupportedPrefixes.Add("MyApp.Models");
// Act
services.AddOrleansSerialization(options);
var provider = services.BuildServiceProvider();
// Assert
var serializer = provider.GetService<ISerializer>();
serializer.Should().NotBeNull();
}
Testing Grain Serialization
[Fact]
public async Task Grain_ShouldSerializeCustomTypes()
{
// Arrange
var cluster = await CreateTestCluster(options =>
{
options.SupportedPrefixes.Add("MyApp.Models");
});
var grain = cluster.GrainFactory.GetGrain<IUserGrain>("test-user");
var profile = new UserProfile { Name = "Test" };
// Act
var result = await grain.UpdateProfileAsync(profile);
// Assert
result.IsSuccess.Should().BeTrue();
}
Dependencies
- Microsoft.Orleans.Sdk: Orleans SDK for distributed applications
- Microsoft.Orleans.Core.Abstractions: Core Orleans abstractions
- Microsoft.Orleans.Serialization.Abstractions: Serialization abstractions
- Microsoft.Orleans.Serialization.SystemTextJson: JSON serialization provider
- Microsoft.Extensions.DependencyInjection.Abstractions: DI abstractions
- Ardalis.Result: Result pattern library (automatically supported)
Related Libraries
- Nabs.Launchpad.Core.Context: Context objects with Orleans serialization
- Nabs.Launchpad.Core.Silo: Orleans silo configuration
- Nabs.Launchpad.Core.SiloClient: Orleans client configuration
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
- Ardalis.Result (>= 10.1.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Orleans.Core.Abstractions (>= 9.2.1)
- Microsoft.Orleans.Sdk (>= 9.2.1)
- Microsoft.Orleans.Serialization.Abstractions (>= 9.2.1)
- Microsoft.Orleans.Serialization.SystemTextJson (>= 9.2.1)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on Nabs.Launchpad.Core.Interfaces:
| Package | Downloads |
|---|---|
|
Nabs.Launchpad.Core.Silo
Package Description |
|
|
Nabs.Launchpad.Core.SiloClient
Package Description |
|
|
Nabs.Launchpad.Core.Testing.Silos
Package Description |
|
|
Nabs.Launchpad.Core.Portal
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 10.0.192 | 88 | 11/28/2025 | |
| 10.0.190 | 101 | 11/27/2025 | |
| 10.0.189 | 166 | 11/23/2025 | |
| 10.0.187 | 164 | 11/23/2025 | |
| 10.0.186 | 154 | 11/23/2025 | |
| 10.0.184 | 406 | 11/20/2025 | |
| 10.0.181-rc3 | 293 | 11/11/2025 | |
| 10.0.180 | 295 | 11/11/2025 | |
| 10.0.179-rc2 | 230 | 11/11/2025 | |
| 10.0.178-rc2 | 188 | 11/10/2025 | |
| 10.0.177-rc2 | 179 | 11/10/2025 | |
| 10.0.176-rc2 | 144 | 11/6/2025 | |
| 10.0.175-rc2 | 146 | 11/6/2025 | |
| 10.0.174-rc2 | 152 | 11/5/2025 | |
| 10.0.173-rc2 | 160 | 11/3/2025 | |
| 10.0.172-rc2 | 173 | 11/2/2025 | |
| 10.0.170-rc2 | 164 | 11/1/2025 | |
| 10.0.169-rc2 | 166 | 11/1/2025 | |
| 10.0.168-rc2 | 161 | 10/31/2025 | |
| 10.0.166-rc2 | 163 | 10/31/2025 | |
| 10.0.164-rc2 | 226 | 10/28/2025 | |
| 10.0.162-rc2 | 220 | 10/24/2025 | |
| 9.0.151 | 248 | 10/17/2025 | |
| 9.0.150 | 298 | 9/10/2025 | |
| 9.0.146 | 256 | 8/15/2025 | |
| 9.0.145 | 305 | 8/11/2025 | |
| 9.0.144 | 312 | 8/8/2025 | |
| 9.0.137 | 226 | 7/29/2025 | |
| 9.0.136 | 236 | 7/29/2025 | |
| 9.0.135 | 280 | 7/28/2025 | |
| 9.0.134 | 303 | 7/9/2025 | |
| 9.0.133 | 317 | 7/9/2025 | |
| 9.0.132 | 316 | 7/9/2025 | |
| 9.0.131 | 318 | 7/9/2025 | |
| 9.0.130 | 318 | 7/7/2025 |