![]() |
VOOZH | about |
dotnet add package SiLA2.AspNetCore --version 10.2.4
NuGet\Install-Package SiLA2.AspNetCore -Version 10.2.4
<PackageReference Include="SiLA2.AspNetCore" Version="10.2.4" />
<PackageVersion Include="SiLA2.AspNetCore" Version="10.2.4" />Directory.Packages.props
<PackageReference Include="SiLA2.AspNetCore" />Project file
paket add SiLA2.AspNetCore --version 10.2.4
#r "nuget: SiLA2.AspNetCore, 10.2.4"
#:package SiLA2.AspNetCore@10.2.4
#addin nuget:?package=SiLA2.AspNetCore&version=10.2.4Install as a Cake Addin
#tool nuget:?package=SiLA2.AspNetCore&version=10.2.4Install as a Cake Tool
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:
.sila.xml files| Package | SiLA2.AspNetCore (NuGet) |
| Repository | https://gitlab.com/SiLA2/sila_csharp |
| License | MIT |
| Target | .NET 10 |
| Dependencies | SiLA2.Core, Microsoft.Extensions.Hosting.Abstractions |
GetKestrelConfigData().sila.xml feature definitions from the Features directoryappsettings.jsonInstall-Package SiLA2.AspNetCore
dotnet add package SiLA2.AspNetCore
<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.
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
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 - IPAddress to bind to (defaults to IPAddress.Any)Item2 - Port numberItem3 - X509Certificate2 for TLS/SSLExample:
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:
ICertificateProvider must be registered in DI containerIServerConfig must be registered in DI containerDiscovers 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:
Features/ subdirectory.sila.xml filesFeature Directory Structure:
MyServer.App/
├── Features/
│ ├── TemperatureController-v1_0.sila.xml
│ ├── DataTypeProvider-v1_0.sila.xml
│ └── SiLAService-v1_0.sila.xml
└── Program.cs
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."
}
}
The writable options pattern extends ASP.NET Core's standard options pattern by enabling runtime updates that persist to disk.
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";
});
}
}
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:
appsettings.json as JSONTHere'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();
}
The GetKestrelConfigData() method parses command-line arguments to override server configuration.
| Argument Position | Description | Example |
|---|---|---|
| 1st argument | IP address or FQHN | 127.0.0.1 or myserver.local |
| 2nd argument | Port number | 50051 |
# 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
IPAddress.Any (0.0.0.0)IServerConfig.PortICertificateProviderSiLA2.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
});
Explore complete working examples in the repository:
Path: src/Examples/TemperatureController/SiLA2.Temperature.Server.App/
Features:
InitializeSiLA2Features()Run:
cd src/Examples/TemperatureController/SiLA2.Temperature.Server.App
dotnet run
# With custom IP/port:
dotnet run -- 127.0.0.1 50051
Path: src/Examples/ShakerController/SiLA2.Shaker.Server.App/
Run:
cd src/Examples/ShakerController/SiLA2.Shaker.Server.App
dotnet run
src/Examples/DataTypeProvider/src/Examples/TemperatureController/SiLA2.Temperature.Server.App.Webfrontend/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
Use writable options for configuration that needs runtime updates:
services.ConfigureWritable<ServerConfig>(
configuration.GetSection("ServerConfig"),
"appsettings.json");
services.AddSingleton<ISiLA2Server, SiLA2Server>();
// NOT AddScoped or AddTransient
services.AddGrpc(options =>
{
options.EnableDetailedErrors = true; // Debug mode only
});
Add validation and logging interceptors:
services.AddGrpc(options =>
{
options.Interceptors.Add<LoggingInterceptor>();
options.Interceptors.Add<MetadataValidationInterceptor>();
options.Interceptors.Add<ParameterValidationInterceptor>();
});
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
Let ICertificateProvider manage certificates automatically:
services.AddSingleton<ICertificateProvider, CertificateProvider>();
// Automatically generates self-signed cert if none exists
Use different appsettings files:
#if DEBUG
var configFile = "appsettings.Development.json";
#else
var configFile = "appsettings.json";
#endif
services.ConfigureWritable<ServerConfig>(
configuration.GetSection("ServerConfig"),
configFile);
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 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.2.4 | 975 | 3/13/2026 |
| 10.2.3 | 157 | 3/7/2026 |
| 10.2.2 | 652 | 2/12/2026 |
| 10.2.1 | 334 | 1/25/2026 |
| 10.2.0 | 464 | 12/23/2025 |
| 10.1.0 | 416 | 11/29/2025 |
| 10.0.0 | 420 | 11/11/2025 |
| 9.0.4 | 532 | 6/25/2025 |
| 9.0.3 | 242 | 6/21/2025 |
| 9.0.2 | 699 | 1/6/2025 |
| 9.0.1 | 334 | 11/17/2024 |
| 9.0.0 | 247 | 11/13/2024 |
| 8.1.2 | 389 | 10/20/2024 |
| 8.1.1 | 820 | 8/31/2024 |
| 8.1.0 | 899 | 2/11/2024 |
| 8.0.0 | 884 | 11/15/2023 |
| 7.5.4 | 2,230 | 10/27/2023 |
| 7.5.3 | 728 | 7/19/2023 |
| 7.5.2 | 458 | 7/3/2023 |
| 7.5.1 | 495 | 6/2/2023 |