SiLA2.AspNetCore
10.3.3
dotnet add package SiLA2.AspNetCore --version 10.3.3
NuGet\Install-Package SiLA2.AspNetCore -Version 10.3.3
<PackageReference Include="SiLA2.AspNetCore" Version="10.3.3" />
<PackageVersion Include="SiLA2.AspNetCore" Version="10.3.3" />
<PackageReference Include="SiLA2.AspNetCore" />
paket add SiLA2.AspNetCore --version 10.3.3
#r "nuget: SiLA2.AspNetCore, 10.3.3"
#:package SiLA2.AspNetCore@10.3.3
#addin nuget:?package=SiLA2.AspNetCore&version=10.3.3
#tool nuget:?package=SiLA2.AspNetCore&version=10.3.3
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
- One-Line Server Setup -
AddSiLA2Server()registers all essential services with a single call - Extension Methods for Dependency Injection - Streamlined service registration with
AddSiLA2CoreServices(),AddSiLA2CertificateServices(), and more - Kestrel Server Configuration - Automatic TLS/SSL certificate handling with
GetKestrelConfigData()andListenSiLA2() SILA_*Environment Variables - Container-friendly configuration compatible with the SiLA-Box- Persistent Container Identity -
SILA_DATA_DIRkeeps the server UUID and certificate across container recreation - 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 with the AddSiLA2Server() extension method:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection;
using SiLA2.AspNetCore;
using SiLA2.Server;
using YourFeature.Services;
var builder = WebApplication.CreateBuilder(args);
// Register all SiLA2 services with one call
builder.Services.AddSiLA2Server(builder.Configuration, options =>
{
options.EnableGrpcReflection = true; // Optional: enable for debugging
});
// Register feature services
builder.Services.AddSingleton<MyFeatureService>();
// Configure Kestrel with automatic certificate handling
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenSiLA2(args.GetKestrelConfigData(options.ApplicationServices));
});
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();
Configuration (appsettings.json):
{
"ServerConfig": {
"Name": "MyDevice",
"UUID": "12345678-1234-1234-1234-123456789012",
"FQHN": "localhost",
"Port": 50051
}
}
Run the server:
dotnet run
# Or with custom IP/port:
dotnet run -- 192.168.1.100 50052
Extension Methods
AddSiLA2Server()
Registers all essential SiLA2 server services with a single call. This is the recommended way to configure a SiLA2 server.
Signature:
public static IServiceCollection AddSiLA2Server(
this IServiceCollection services,
IConfiguration configuration,
Action<SiLA2ServerOptions> configureOptions = null)
Options:
EnableBinaryTransfer- Enable upload/download repositories (default:false)EnableGrpcReflection- Enable gRPC reflection service (default:false)EnableDetailedErrors- Enable detailed gRPC errors (default:true)ServerConfigSectionName- Configuration section name (default:"ServerConfig")
Example:
var builder = WebApplication.CreateBuilder(args);
// Register all SiLA2 services with one call
builder.Services.AddSiLA2Server(builder.Configuration, options =>
{
options.EnableBinaryTransfer = true;
options.EnableGrpcReflection = true;
});
// Register feature-specific services
builder.Services.AddSingleton<MyFeatureService>();
Services Registered:
- gRPC with standard SiLA2 interceptors (Logging, MetadataValidation, ParameterValidation)
MetadataManagerfor handling request/response metadata- Network discovery services (
ServiceDiscoveryInfo,ServerInformation,IServiceAnnouncer) - Core server services (
ISiLA2Server,IServerDataProvider,IGrpcChannelProvider) - Certificate services (
ICertificateProvider,ICertificateContext,ICertificateRepository) - Observable command support (
IObservableCommandManager<,>) IServerConfigfrom configuration
AddSiLA2Grpc()
Adds gRPC services with standard SiLA2 interceptors for logging, metadata validation, and parameter validation.
Signature:
public static IServiceCollection AddSiLA2Grpc(
this IServiceCollection services,
bool enableDetailedErrors = true)
Example:
// Use this if you need more control than AddSiLA2Server provides
services.AddSiLA2Grpc(enableDetailedErrors: true);
Interceptors Added:
LoggingInterceptor- Logs all incoming requests and errorsMetadataValidationInterceptor- Validates request metadataParameterValidationInterceptor- Validates request parameters
AddSiLA2CoreServices()
Adds core SiLA2 server services. Use this if you need granular control over service registration.
Signature:
public static IServiceCollection AddSiLA2CoreServices(this IServiceCollection services)
Services Registered:
| Service | Lifetime |
|---------|----------|
| MetadataManager | Singleton |
| IObservableCommandManager<,> | Singleton (open generic) |
| INetworkService | Transient |
| ServiceDiscoveryInfo | Singleton |
| ServerInformation | Singleton |
| IServiceAnnouncer | Transient |
| ISiLA2Server | Singleton |
| IGrpcChannelProvider | Singleton |
| IServerDataProvider | Scoped |
AddSiLA2CertificateServices()
Adds TLS/SSL certificate services for secure gRPC communication.
Signature:
public static IServiceCollection AddSiLA2CertificateServices(
this IServiceCollection services,
IConfiguration configuration = null)
Services Registered:
| Service | Lifetime |
|---------|----------|
| ICertificateProvider | Singleton |
| ICertificateContext | Singleton |
| ICertificateRepository | Singleton |
When configuration is supplied and SILA_DATA_DIR is set, the certificate store is pointed at
that directory instead of the assembly directory. AddSiLA2Server() passes the configuration
automatically; the parameter is optional so existing call sites keep working unchanged.
AddSiLA2BinaryTransfer()
Adds binary transfer services for file upload and download functionality.
Signature:
public static IServiceCollection AddSiLA2BinaryTransfer(this IServiceCollection services)
Services Registered:
| Service | Lifetime |
|---------|----------|
| IBinaryUploadRepository | Singleton |
| IBinaryDownloadRepository | Singleton |
AddSiLA2ServerConfig()
Adds IServerConfig from the application configuration with writable options support.
Signature:
public static IServiceCollection AddSiLA2ServerConfig(
this IServiceCollection services,
IConfiguration configuration,
string sectionName = "ServerConfig")
Required Configuration Values:
Name- The server display nameUUID- The server unique identifier (GUID)FQHN- The fully qualified host name or IP addressPort- The server port number
Optional Configuration Values:
NetworkInterface- The network interface to bind toDiscoveryServiceName- The mDNS service name
Example (appsettings.json):
{
"ServerConfig": {
"Name": "MyDevice",
"UUID": "12345678-1234-1234-1234-123456789012",
"FQHN": "localhost",
"Port": 50051,
"NetworkInterface": "0.0.0.0",
"DiscoveryServiceName": "_sila2._tcp.local."
}
}
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, ornullwhenSILA_TLS=false
Example:
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenSiLA2(args.GetKestrelConfigData(options.ApplicationServices));
});
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
ListenSiLA2()
Binds Kestrel to the address, port and certificate returned by GetKestrelConfigData().
Signature:
public static void ListenSiLA2(
this KestrelServerOptions serverOptions,
Tuple<IPAddress, int, X509Certificate2> configData)
Example:
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenSiLA2(args.GetKestrelConfigData(options.ApplicationServices));
});
Prefer this over calling Listen(...) and UseHttps(...) yourself. It handles two failure modes
that are silent otherwise:
UseHttps(null)does not disable TLS. Kestrel falls back to the ASP.NET Core development certificate, so a server started withSILA_TLS=falsestill serves HTTPS — with a certificate no SiLA client trusts.- A plaintext
Http1AndHttp2endpoint is not a gRPC endpoint. HTTP/2 is normally negotiated through TLS ALPN, so without TLS Kestrel resolves the endpoint down to HTTP/1.1 (logging "HTTP/2 is not enabled … Connections to this endpoint will use HTTP/1.1") and gRPC stops working entirely.ListenSiLA2()setsHttpProtocols.Http2explicitly on the plaintext path, so cleartext gRPC is served as h2c.
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
Simplified Setup (Recommended)
Using AddSiLA2Server() for a clean, production-ready setup:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection;
using SiLA2.AspNetCore;
using SiLA2.Server;
using YourFeature.Services;
var builder = WebApplication.CreateBuilder(args);
// ===== Configure Services =====
builder.Services.AddSiLA2Server(builder.Configuration, options =>
{
options.EnableBinaryTransfer = true;
options.EnableGrpcReflection = true;
options.EnableDetailedErrors = true; // Set false in production
});
// Feature services
builder.Services.AddSingleton<YourFeatureService>();
builder.Services.AddSingleton<LockControllerService>();
builder.Services.AddSingleton(sp => ActivatorUtilities.CreateInstance<AuthenticationService>(sp));
// ===== Configure Kestrel =====
// ListenSiLA2 applies the endpoint defaults, enables HTTPS when a certificate is
// present, and serves cleartext gRPC as h2c when SILA_TLS=false.
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenSiLA2(args.GetKestrelConfigData(options.ApplicationServices));
});
var app = builder.Build();
// ===== Configure Application =====
var siLA2Server = app.Services.GetRequiredService<ISiLA2Server>();
app.InitializeSiLA2Features(siLA2Server);
// Map gRPC services
app.MapGrpcService<SiLAService>();
app.MapGrpcService<YourFeatureService>();
app.MapGrpcService<LockControllerService>();
app.MapGrpcService<AuthenticationService>();
// Optional: gRPC reflection (if enabled)
app.MapGrpcReflectionService();
// Start mDNS announcement
siLA2Server.Start();
app.Run();
Advanced Setup (Fine-Grained Control)
For cases where you need precise control over service registration:
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 =====
// ListenSiLA2 applies the endpoint defaults, enables HTTPS when a certificate is
// present, and serves cleartext gRPC as h2c when SILA_TLS=false.
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenSiLA2(args.GetKestrelConfigData(options.ApplicationServices));
});
var app = builder.Build();
// ===== Configure Application =====
ConfigureApplication(app);
app.Run();
// ===== Service Registration =====
void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
// Use individual extension methods for granular control
services.AddSiLA2Grpc(enableDetailedErrors: true);
services.AddSiLA2CoreServices();
services.AddSiLA2CertificateServices();
services.AddSiLA2BinaryTransfer();
services.AddSiLA2ServerConfig(configuration);
// Feature services
services.AddSingleton<YourFeatureService>();
services.AddSingleton<LockControllerService>();
services.AddSingleton(sp => ActivatorUtilities.CreateInstance<AuthenticationService>(sp));
}
// ===== 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
SILA_* Environment Variables
Servers read their configuration from flat SILA_* environment variables in addition to
appsettings.json. These are the names used by the
SiLA-Box, whose box manager assigns each installed
service a free SILA_PORT and forces SILA_HOST — a server that ignores them is unreachable and
reported as "reachable but not a SiLA server".
AddSiLA2Server() registers the source automatically, so no code change is needed in existing
servers.
Supported Variables
| Variable | Maps to | Description |
|---|---|---|
SILA_HOST |
ServerConfig:FQHN |
Interface to bind to |
SILA_PORT |
ServerConfig:Port |
TCP port (0-65535) |
SILA_TLS |
ServerConfig:Tls |
Enable TLS. Accepts 1/true/yes/on and 0/false/no/off |
SILA_DATA_DIR |
ServerConfig:DataDir |
Directory for the server UUID and generated certificates |
SILA_SERVER_NAME |
ServerConfig:Name |
Name advertised on the network |
SILA_SERVER_UUID |
ServerConfig:UUID |
Stable unique identifier |
SILA_SERVER_TYPE |
ServerInfo:Type |
Type identifier |
SILA_SERVER_VERSION |
ServerInfo:Version |
Server version |
SILA_SERVER_DESCRIPTION |
ServerInfo:Description |
Description advertised on the network |
SILA_VENDOR_URL |
ServerInfo:VendorURI |
Vendor website |
SILA_CERT_FILE / SILA_KEY_FILE |
ServerConfig:CertFile / :KeyFile |
Optional PEM certificate chain and private key |
Names are declared once in SilaEnvironmentVariables, so referring to them from code needs no
string literals.
Precedence
command line > SILA_* > ServerConfig__* > appsettings.json
An unset or empty variable changes nothing, so existing deployments are unaffected. docker run -e SILA_HOST= produces a present-but-empty variable, which is treated as unset rather than blanking
out the configured bind address.
Invalid values fail fast at startup rather than being silently ignored — a server that quietly disregards the port it was assigned is far harder to diagnose than one that refuses to start:
System.InvalidOperationException: Environment variable 'SILA_PORT' must be between 0 and 65535, got 99999.
Manual Registration
Applications that do not use AddSiLA2Server(), or that hold a plain IConfiguration rather than a
ConfigurationManager, can add the source themselves. The call is idempotent:
using SiLA2.AspNetCore.Configuration;
builder.Configuration.AddSilaEnvironmentVariables();
Persistent Identity with SILA_DATA_DIR
SiLA 2 requires a server's UUID to stay constant across restarts, and clients trust a server's self-signed certificate on first use. In a container both live on a writable volume, or they are lost whenever the container is recreated.
Setting SILA_DATA_DIR stores both there:
| File | Contents |
|---|---|
server.uuid |
The server UUID |
server.crt / server.key |
The generated self-signed certificate |
ca.crt / ca.key |
The generated certificate authority |
docker run -d --network host \
-e SILA_HOST=0.0.0.0 -e SILA_PORT=40050 \
-v my-server-data:/data \
my-sila-server:latest
UUID Resolution Order
SILA_SERVER_UUID, if set- A persisted
$SILA_DATA_DIR/server.uuid - A newly generated UUID — only when
SILA_DATA_DIRis set, then written there ServerConfig:UUIDfromappsettings.json, when no data directory is configured
Step 3 matters for containers: appsettings.json ships inside an image, so without it every
container started from one image would advertise the same UUID and two instances on a box would be
indistinguishable. Configuring a data directory is the signal that the server owns its identity
there. Set SILA_SERVER_UUID to pin a specific value.
Step 4 means behaviour is unchanged for servers that do not set SILA_DATA_DIR.
An unwritable SILA_DATA_DIR is a startup error, not a warning — a container that cannot persist
its identity would otherwise regenerate it on every restart and surface much later as a server that
inexplicably changed UUID.
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. Use AddSiLA2Server() for New Projects
// Recommended: registers all services with correct lifetimes
builder.Services.AddSiLA2Server(builder.Configuration);
// Only use individual methods if you need fine-grained control
services.AddSiLA2CoreServices();
services.AddSiLA2CertificateServices();
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
- Grpc.AspNetCore (>= 2.84.0)
- Grpc.AspNetCore.Server.Reflection (>= 2.84.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.12)
- SiLA2.Core (>= 10.3.3)
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.3.3 | 209 | 10/6/2026 |
| 10.3.2 | 141 | 9/27/2026 |
| 10.3.1 | 129 | 9/26/2026 |
| 10.3.0 | 710 | 7/26/2026 |
| 10.2.6 | 508 | 7/5/2026 |
| 10.2.5 | 149 | 7/4/2026 |
| 10.2.4 | 1,499 | 3/13/2026 |
| 10.2.3 | 186 | 3/7/2026 |
| 10.2.2 | 874 | 2/12/2026 |
| 10.2.1 | 360 | 1/25/2026 |
| 10.2.0 | 492 | 12/23/2025 |
| 10.1.0 | 438 | 11/29/2025 |
| 10.0.0 | 448 | 11/11/2025 |
| 9.0.4 | 563 | 6/25/2025 |
| 9.0.3 | 264 | 6/21/2025 |
| 9.0.2 | 725 | 1/6/2025 |
| 9.0.1 | 357 | 11/17/2024 |
| 9.0.0 | 271 | 11/13/2024 |
| 8.1.2 | 417 | 10/20/2024 |
| 8.1.1 | 844 | 8/31/2024 |