SiLA2.AspNetCore
10.2.2
dotnet add package SiLA2.AspNetCore --version 10.2.2
NuGet\Install-Package SiLA2.AspNetCore -Version 10.2.2
<PackageReference Include="SiLA2.AspNetCore" Version="10.2.2" />
<PackageVersion Include="SiLA2.AspNetCore" Version="10.2.2" />
<PackageReference Include="SiLA2.AspNetCore" />
paket add SiLA2.AspNetCore --version 10.2.2
#r "nuget: SiLA2.AspNetCore, 10.2.2"
#:package SiLA2.AspNetCore@10.2.2
#addin nuget:?package=SiLA2.AspNetCore&version=10.2.2
#tool nuget:?package=SiLA2.AspNetCore&version=10.2.2
SiLA2.AspNetCore
ASP.NET Core Integration Utilities for SiLA2 Servers
SiLA2.AspNetCore is the integration layer between ASP.NET Core and the SiLA2 C# implementation, providing essential extension methods, configuration utilities, and dependency injection patterns for building production-ready SiLA2 gRPC servers.
This module simplifies server setup by automating common tasks like:
- Dependency injection configuration
- Kestrel web server setup with automatic TLS/SSL certificate handling
- SiLA2 feature initialization from
.sila.xmlfiles - Writable configuration pattern for runtime settings updates
- Command-line argument parsing for server configuration
| Package | SiLA2.AspNetCore (NuGet) |
| Repository | https://gitlab.com/SiLA2/sila_csharp |
| License | MIT |
| Target | .NET 10 |
| Dependencies | SiLA2.Core, Microsoft.Extensions.Hosting.Abstractions |
Key Features
- Extension Methods for Dependency Injection - Streamlined service registration for SiLA2 components
- Kestrel Server Configuration - Automatic TLS/SSL certificate handling with
GetKestrelConfigData() - Feature Auto-Discovery - Loads all
.sila.xmlfeature definitions from the Features directory - Writable Options Pattern - Runtime configuration updates that persist to
appsettings.json - Command-Line Argument Parsing - Override server IP, port, and certificate via CLI arguments
- Integration with SiLA2.Utils - Seamless connection to networking, security, and configuration services
Installation
NuGet Package Manager
Install-Package SiLA2.AspNetCore
.NET CLI
dotnet add package SiLA2.AspNetCore
Project Reference (Development)
<ItemGroup>
<ProjectReference Include="..\SiLA2.AspNetCore\SiLA2.AspNetCore.csproj" />
</ItemGroup>
Note: This package is required for all ASP.NET Core-based SiLA2 servers. It depends on SiLA2.Core which will be installed automatically.
Quick Start
Here's a minimal SiLA2 server using ASP.NET Core:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection;
using SiLA2.AspNetCore;
using SiLA2.Server;
using SiLA2.Utils.Config;
using SiLA2.Utils.Network;
using SiLA2.Utils.Security;
using YourFeature.Services;
var builder = WebApplication.CreateBuilder(args);
// Register SiLA2 services
builder.Services.AddGrpc();
builder.Services.AddSingleton<ISiLA2Server, SiLA2Server>();
builder.Services.AddSingleton<ICertificateProvider, CertificateProvider>();
builder.Services.AddSingleton<IServerConfig>(new ServerConfig(
name: "MyDevice",
uuid: Guid.NewGuid(),
fqhn: "localhost",
port: 50051));
// Register feature services
builder.Services.AddSingleton<MyFeatureService>();
// Configure Kestrel with automatic certificate handling
builder.WebHost.ConfigureKestrel(options =>
{
var (ipAddress, port, certificate) = args.GetKestrelConfigData(
options.ApplicationServices);
options.ConfigureEndpointDefaults(
endpoints => endpoints.Protocols = HttpProtocols.Http1AndHttp2);
options.Listen(ipAddress, port,
listenOptions => listenOptions.UseHttps(certificate));
});
var app = builder.Build();
// Initialize SiLA2 features from Features/*.sila.xml files
var siLA2Server = app.Services.GetRequiredService<ISiLA2Server>();
app.InitializeSiLA2Features(siLA2Server);
// Map gRPC services
app.MapGrpcService<MyFeatureService>();
// Start mDNS announcement
siLA2Server.Start();
app.Run();
Run the server:
dotnet run
# Or with custom IP/port:
dotnet run -- 192.168.1.100 50052
Extension Methods
GetKestrelConfigData()
Parses command-line arguments and retrieves Kestrel server configuration (IP address, port, TLS certificate).
Signature:
public static Tuple<IPAddress, int, X509Certificate2> GetKestrelConfigData(
this string[] args,
IServiceProvider serviceProvider)
Returns:
Item1-IPAddressto bind to (defaults toIPAddress.Any)Item2- Port numberItem3-X509Certificate2for TLS/SSL
Example:
builder.WebHost.ConfigureKestrel(options =>
{
var (ipAddress, port, certificate) = args.GetKestrelConfigData(
options.ApplicationServices);
options.Listen(ipAddress, port, listenOptions =>
{
listenOptions.UseHttps(certificate);
});
});
Command-Line Arguments:
# Override IP and port
dotnet run -- 127.0.0.1 50051
# Use default configuration
dotnet run
Requirements:
ICertificateProvidermust be registered in DI containerIServerConfigmust be registered in DI container
InitializeSiLA2Features()
Discovers and loads all .sila.xml feature definition files from the Features/ directory into the SiLA2 server.
Signature:
public static void InitializeSiLA2Features(
this IHost host,
ISiLA2Server siLA2Server)
Example:
var app = builder.Build();
var siLA2Server = app.Services.GetRequiredService<ISiLA2Server>();
// Load all Features/*.sila.xml files
app.InitializeSiLA2Features(siLA2Server);
// Now map gRPC services
app.MapGrpcService<TemperatureControllerService>();
Initialization Order (Critical):
1. builder.Build() → creates IHost
2. app.InitializeSiLA2Features(siLA2Server) → loads .sila.xml files
3. app.MapGrpcService<T>() → registers gRPC endpoints
4. siLA2Server.Start() → announces services via mDNS
5. app.Run() → starts server
What It Does:
- Finds the assembly's
Features/subdirectory - Discovers all
.sila.xmlfiles - Loads feature definitions into the server for:
- Parameter validation
- Error handling
- Metadata access
- Server introspection
Feature Directory Structure:
MyServer.App/
├── Features/
│ ├── TemperatureController-v1_0.sila.xml
│ ├── DataTypeProvider-v1_0.sila.xml
│ └── SiLAService-v1_0.sila.xml
└── Program.cs
ConfigureWritable<T>()
Registers the writable options pattern, enabling runtime configuration updates that persist to appsettings.json.
Signature:
public static void ConfigureWritable<T>(
this IServiceCollection services,
IConfigurationSection section,
string file = "appsettings.json") where T : class, new()
Example:
// In Program.cs
services.ConfigureWritable<ServerConfig>(
configuration.GetSection("ServerConfig"),
"appsettings.json");
// In a service
public class MyService
{
private readonly IWritableOptions<ServerConfig> _settings;
public MyService(IWritableOptions<ServerConfig> settings)
{
_settings = settings;
}
public void UpdateServerPort(int newPort)
{
// Updates configuration and persists to appsettings.json
_settings.Update(config => config.Port = newPort);
}
public int GetCurrentPort()
{
return _settings.Value.Port;
}
}
Configuration File Example (appsettings.json):
{
"ServerConfig": {
"Name": "TemperatureController",
"UUID": "12345678-1234-1234-1234-123456789012",
"FQHN": "localhost",
"Port": 50051,
"NetworkInterface": "0.0.0.0",
"DiscoveryServiceName": "_sila2._tcp.local."
}
}
Writable Options Pattern
The writable options pattern extends ASP.NET Core's standard options pattern by enabling runtime updates that persist to disk.
Standard Options vs. Writable Options
Standard Options (Read-Only):
public class MyService
{
private readonly IOptions<ServerConfig> _options;
public MyService(IOptions<ServerConfig> options)
{
_options = options;
// Can only READ configuration
var port = _options.Value.Port;
}
}
Writable Options (Read-Write):
public class MyService
{
private readonly IWritableOptions<ServerConfig> _options;
public MyService(IWritableOptions<ServerConfig> options)
{
_options = options;
}
public void UpdateConfiguration()
{
// Can READ configuration
var currentPort = _options.Value.Port;
// Can WRITE configuration (persists to appsettings.json)
_options.Update(config =>
{
config.Port = 8080;
config.FQHN = "192.168.1.100";
});
}
}
Complete Example
1. Define Configuration Class:
public class ServerConfig
{
public string Name { get; set; }
public Guid UUID { get; set; }
public string FQHN { get; set; }
public int Port { get; set; }
}
2. Register Writable Options:
// In Program.cs
services.ConfigureWritable<ServerConfig>(
configuration.GetSection("ServerConfig"),
"appsettings.json");
3. Inject and Use:
public class ServerConfigurationService
{
private readonly IWritableOptions<ServerConfig> _config;
private readonly ILogger<ServerConfigurationService> _logger;
public ServerConfigurationService(
IWritableOptions<ServerConfig> config,
ILogger<ServerConfigurationService> logger)
{
_config = config;
_logger = logger;
}
public void ChangeServerPort(int newPort)
{
_config.Update(settings =>
{
settings.Port = newPort;
});
_logger.LogInformation($"Server port updated to {newPort}");
// appsettings.json is now updated with new port
}
}
How It Works:
- Reads
appsettings.jsonas JSON - Deserializes the specified section to type
T - Applies your changes via the lambda
- Serializes back to JSON
- Writes to disk with indented formatting
- Reloads configuration so all services see updated values
Complete Server Setup Example
Here's a production-ready SiLA2 server template:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SiLA2.AspNetCore;
using SiLA2.Commands;
using SiLA2.Server;
using SiLA2.Server.Services;
using SiLA2.Utils.Config;
using SiLA2.Utils.gRPC;
using SiLA2.Utils.Network;
using SiLA2.Utils.Security;
using YourFeature.Services;
var builder = WebApplication.CreateBuilder(args);
// ===== Configure Services =====
ConfigureServices(builder.Services, builder.Configuration);
// ===== Configure Kestrel =====
builder.WebHost.ConfigureKestrel(options =>
{
var (ipAddress, port, certificate) = args.GetKestrelConfigData(
options.ApplicationServices);
options.ConfigureEndpointDefaults(
endpoints => endpoints.Protocols = HttpProtocols.Http1AndHttp2);
options.Listen(ipAddress, port, listenOptions =>
{
listenOptions.UseHttps(certificate);
});
});
var app = builder.Build();
// ===== Configure Application =====
ConfigureApplication(app);
app.Run();
// ===== Service Registration =====
void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
// gRPC configuration
services.AddGrpc(options =>
{
options.EnableDetailedErrors = true;
options.Interceptors.Add<SiLA2.Server.Interceptors.LoggingInterceptor>();
options.Interceptors.Add<SiLA2.Server.Interceptors.MetadataValidationInterceptor>();
options.Interceptors.Add<SiLA2.Server.Interceptors.ParameterValidationInterceptor>();
});
// Core SiLA2 services
services.AddSingleton<ISiLA2Server, SiLA2Server>();
services.AddSingleton<IGrpcChannelProvider, GrpcChannelProvider>();
services.AddSingleton(typeof(IObservableCommandManager<,>),
typeof(ObservableCommandManager<,>));
// Security and networking
services.AddSingleton<ICertificateProvider, CertificateProvider>();
services.AddSingleton<ICertificateContext, CertificateContext>();
services.AddTransient<INetworkService, NetworkService>();
// Server configuration
var serverConfig = new ServerConfig(
name: configuration["ServerConfig:Name"],
uuid: Guid.Parse(configuration["ServerConfig:UUID"]),
fqhn: configuration["ServerConfig:FQHN"],
port: int.Parse(configuration["ServerConfig:Port"]),
networkInterface: configuration["ServerConfig:NetworkInterface"],
discoveryServiceName: configuration["ServerConfig:DiscoveryServiceName"]);
services.AddSingleton<IServerConfig>(serverConfig);
// Writable options for runtime configuration updates
services.ConfigureWritable<ServerConfig>(
configuration.GetSection("ServerConfig"),
"appsettings.json");
// Feature services
services.AddSingleton<YourFeatureService>();
services.AddSingleton<LockControllerService>();
services.AddSingleton<AuthenticationService>();
}
// ===== Application Configuration =====
void ConfigureApplication(WebApplication app)
{
var siLA2Server = app.Services.GetRequiredService<ISiLA2Server>();
// Initialize features from Features/*.sila.xml
app.InitializeSiLA2Features(siLA2Server);
// Map gRPC services
app.MapGrpcService<SiLAService>();
app.MapGrpcService<YourFeatureService>();
app.MapGrpcService<LockControllerService>();
app.MapGrpcService<AuthenticationService>();
// Optional: gRPC reflection for debugging
app.MapGrpcReflectionService();
// Start mDNS announcement
siLA2Server.Start();
}
Command-Line Arguments
The GetKestrelConfigData() method parses command-line arguments to override server configuration.
Supported Arguments
| Argument Position | Description | Example |
|---|---|---|
| 1st argument | IP address or FQHN | 127.0.0.1 or myserver.local |
| 2nd argument | Port number | 50051 |
Examples
# Default configuration from appsettings.json
dotnet run
# Override IP address
dotnet run -- 192.168.1.100
# Override IP and port
dotnet run -- 192.168.1.100 8080
# Use localhost
dotnet run -- 127.0.0.1 50051
Fallback Behavior
- If no IP is provided or IP parsing fails →
IPAddress.Any(0.0.0.0) - If no port is provided → Value from
IServerConfig.Port - Certificate is always loaded from
ICertificateProvider
Integration with SiLA2.Utils
SiLA2.AspNetCore depends on services from SiLA2.Utils for core functionality:
| Service | Purpose | Used By |
|---|---|---|
ICertificateProvider |
Loads/generates TLS certificates | GetKestrelConfigData() |
IServerConfig |
Server configuration (name, UUID, port, FQHN) | GetKestrelConfigData() |
INetworkService |
Network operations (IP resolution, interface discovery) | Feature services |
IServiceAnnouncer |
mDNS service announcement | ISiLA2Server.Start() |
Dependency Chain:
SiLA2.AspNetCore
└─ SiLA2.Core (SiLA2.dll)
└─ SiLA2.Utils
├─ Security (ICertificateProvider)
├─ Config (IServerConfig)
└─ Network (INetworkService, mDNS)
Example: Certificate Provider Registration:
// Register certificate provider
services.AddSingleton<ICertificateProvider, CertificateProvider>();
services.AddSingleton<ICertificateContext, CertificateContext>();
services.AddSingleton<ICertificateRepository, CertificateRepository>();
// Kestrel will automatically use the provider
builder.WebHost.ConfigureKestrel(options =>
{
var (_, _, certificate) = args.GetKestrelConfigData(options.ApplicationServices);
// certificate is loaded from ICertificateProvider
});
Working Examples
Explore complete working examples in the repository:
Temperature Controller Example
Path: src/Examples/TemperatureController/SiLA2.Temperature.Server.App/
Features:
- Complete ASP.NET Core setup with
InitializeSiLA2Features() - Kestrel configuration with command-line argument parsing
- Writable options for server configuration
- gRPC interceptors for validation and logging
- mDNS service announcement
Run:
cd src/Examples/TemperatureController/SiLA2.Temperature.Server.App
dotnet run
# With custom IP/port:
dotnet run -- 127.0.0.1 50051
Shaker Controller Example
Path: src/Examples/ShakerController/SiLA2.Shaker.Server.App/
Run:
cd src/Examples/ShakerController/SiLA2.Shaker.Server.App
dotnet run
Other Examples
- Data Type Provider:
src/Examples/DataTypeProvider/ - Web Frontend Server:
src/Examples/TemperatureController/SiLA2.Temperature.Server.App.Webfrontend/
Best Practices
1. Initialization Order
Always follow this sequence:
var app = builder.Build(); // 1. Build host
app.InitializeSiLA2Features(siLA2Server); // 2. Load .sila.xml files
app.MapGrpcService<MyFeatureService>(); // 3. Map gRPC endpoints
siLA2Server.Start(); // 4. Announce via mDNS
app.Run(); // 5. Start server
2. Writable Options for Server Settings
Use writable options for configuration that needs runtime updates:
services.ConfigureWritable<ServerConfig>(
configuration.GetSection("ServerConfig"),
"appsettings.json");
3. Register ISiLA2Server as Singleton
services.AddSingleton<ISiLA2Server, SiLA2Server>();
// NOT AddScoped or AddTransient
4. Enable Detailed Errors in Development
services.AddGrpc(options =>
{
options.EnableDetailedErrors = true; // Debug mode only
});
5. Use gRPC Interceptors
Add validation and logging interceptors:
services.AddGrpc(options =>
{
options.Interceptors.Add<LoggingInterceptor>();
options.Interceptors.Add<MetadataValidationInterceptor>();
options.Interceptors.Add<ParameterValidationInterceptor>();
});
6. Feature Directory Structure
Place .sila.xml files in Features/ directory:
MyServer.App/
├── Features/
│ ├── MyFeature-v1_0.sila.xml ← Feature definitions
│ └── AnotherFeature-v1_0.sila.xml
├── Services/
│ └── MyFeatureService.cs ← Service implementations
└── Program.cs
7. Certificate Handling
Let ICertificateProvider manage certificates automatically:
services.AddSingleton<ICertificateProvider, CertificateProvider>();
// Automatically generates self-signed cert if none exists
8. Development vs. Production Configuration
Use different appsettings files:
#if DEBUG
var configFile = "appsettings.Development.json";
#else
var configFile = "appsettings.json";
#endif
services.ConfigureWritable<ServerConfig>(
configuration.GetSection("ServerConfig"),
configFile);
Additional Resources
- SiLA2 C# Wiki: https://gitlab.com/SiLA2/sila_csharp/-/wikis/home
- Main Repository: https://gitlab.com/SiLA2/sila_csharp
- SiLA Standard: https://sila-standard.com
- ASP.NET Core Documentation: https://learn.microsoft.com/aspnet/core
- gRPC for .NET: https://learn.microsoft.com/aspnet/core/grpc
- Open Issues: https://gitlab.com/SiLA2/sila_csharp/-/issues
Contribution
It's Open Source (License: MIT). Feel free to use or contribute!
Repository: https://gitlab.com/SiLA2/sila_csharp
Maintainer: Christoph Pohl (@Chamundi)
| 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.Extensions.Hosting.Abstractions (>= 10.0.3)
- SiLA2.Core (>= 10.2.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.2.2 | 154 | 2/12/2026 |
| 10.2.1 | 266 | 1/25/2026 |
| 10.2.0 | 429 | 12/23/2025 |
| 10.1.0 | 380 | 11/29/2025 |
| 10.0.0 | 385 | 11/11/2025 |
| 9.0.4 | 498 | 6/25/2025 |
| 9.0.3 | 214 | 6/21/2025 |
| 9.0.2 | 667 | 1/6/2025 |
| 9.0.1 | 305 | 11/17/2024 |
| 9.0.0 | 217 | 11/13/2024 |
| 8.1.2 | 351 | 10/20/2024 |
| 8.1.1 | 756 | 8/31/2024 |
| 8.1.0 | 861 | 2/11/2024 |
| 8.0.0 | 862 | 11/15/2023 |
| 7.5.4 | 2,068 | 10/27/2023 |
| 7.5.3 | 667 | 7/19/2023 |
| 7.5.2 | 437 | 7/3/2023 |
| 7.5.1 | 478 | 6/2/2023 |
| 7.4.6 | 398 | 5/21/2023 |
| 7.4.5 | 391 | 5/7/2023 |