SiLA2.Communication 10.2.2

dotnet add package SiLA2.Communication --version 10.2.2
                    
NuGet\Install-Package SiLA2.Communication -Version 10.2.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SiLA2.Communication" Version="10.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SiLA2.Communication" Version="10.2.2" />
                    
Directory.Packages.props
<PackageReference Include="SiLA2.Communication" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SiLA2.Communication --version 10.2.2
                    
#r "nuget: SiLA2.Communication, 10.2.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SiLA2.Communication@10.2.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SiLA2.Communication&version=10.2.2
                    
Install as a Cake Addin
#tool nuget:?package=SiLA2.Communication&version=10.2.2
                    
Install as a Cake Tool

SiLA2.Communication

Runtime Dynamic Protobuf Generation for SiLA2 Features

NuGet Package SiLA2.Communication on NuGet.org
Repository https://gitlab.com/SiLA2/sila_csharp
SiLA Standard https://sila-standard.com
License MIT

Overview

SiLA2.Communication is a specialized component of the sila_csharp implementation that enables dynamic gRPC communication with SiLA2 servers using runtime-generated protobuf types. This eliminates the need for compile-time code generation when working with SiLA2 Feature Definition Language (FDL) files.

Key Value Proposition

Standard Approach (Compile-time):

.sila.xml (FDL) → XSLT → .proto → protoc → C# gRPC stubs → Compiled Assembly

Dynamic Approach (Runtime):

.sila.xml (FDL) → Runtime IL Emission → Dynamic Types → Reflection-based gRPC calls

This package is ideal for:

  • Universal SiLA2 clients that need to connect to any SiLA2 server without pre-compiling feature definitions
  • Runtime feature discovery where features are loaded dynamically from server metadata
  • Testing tools that need to interact with multiple SiLA2 features without maintaining separate assemblies
  • Development environments where rapid iteration is more important than peak performance

When to Use This vs Standard Approach

Scenario Use SiLA2.Communication Use Standard Approach
Building a universal SiLA2 client ✅ Yes ❌ No
Runtime feature loading ✅ Yes ❌ No
Testing multiple features ✅ Yes ⚠️ Optional
Production feature implementation ⚠️ Optional ✅ Yes (better performance)
Static feature set known at compile time ❌ No ✅ Yes

Installation

Install via NuGet Package Manager:

dotnet add package SiLA2.Communication

Or via Package Manager Console:

Install-Package SiLA2.Communication

Requirements

  • .NET 10.0+
  • SiLA2.Core (automatically installed as dependency)
  • protobuf-net 3.2.56+
  • protobuf-net.Grpc 1.2.2+
  • Grpc.AspNetCore 2.76.0+

Core Concepts

1. Feature Definition Language (FDL) to Protobuf Mapping

SiLA2 features are defined in XML files following the SiLA2 FDL schema. This package analyzes FDL metadata at runtime to generate corresponding protobuf message types:


<Feature>
  <Identifier>TemperatureController</Identifier>
  <Command>
    <Identifier>SetTemperature</Identifier>
    <Parameter>
      <Identifier>Temperature</Identifier>
      <DataType>
        <Basic>Real</Basic>
      </DataType>
    </Parameter>
  </Command>
</Feature>

At runtime, this generates a protobuf-compatible type equivalent to:

[ProtoContract]
public class TemperatureController_SetTemperature_DynamicProtobufRequest
{
    [ProtoMember(1)]
    public Real Temperature { get; set; }
}

2. Runtime IL Emission for Type Generation

The package uses .NET Reflection.Emit to generate types at runtime using IL (Intermediate Language) instructions. This is more efficient than using dynamic or ExpandoObject because it creates actual .NET types that can be serialized by protobuf-net.

Types are cached in a shared ModuleBuilder to avoid duplicate generation and improve performance.

3. Four SiLA2 Operation Patterns

The package supports all SiLA2 communication patterns defined in the standard:

Pattern gRPC Pattern Description Use Case
Unobservable Property Unary Get current value immediately Device status, configuration values
Observable Property Server Streaming Subscribe to continuous updates Temperature monitoring, sensor readings
Unobservable Command Unary Execute and return result immediately Set parameter, calibrate sensor
Observable Command Multiple RPCs Long-running operation with progress tracking Start pump, run experiment
Observable Command Flow

Observable commands are the most complex pattern, involving multiple gRPC calls:

  1. Initiate: ExecuteObservableCommand() → Returns CommandConfirmation with CommandExecutionUUID
  2. Monitor Progress: Subscribe to {Command}_Info stream → Receives ExecutionInfo updates
  3. Monitor Intermediate Results (optional): Subscribe to {Command}_Intermediate stream
  4. Retrieve Result: GetObservableCommandResult() after command completes

4. SiLA2 Data Type Support

The package handles all SiLA2 data types:

  • Basic Types: String, Integer, Real, Boolean, Date, Time, Timestamp, Binary, Any
  • Constrained Types: Types with value constraints (min/max, regex patterns)
  • List Types: Repeated fields using Google.Protobuf.Collections.RepeatedField<T>
  • Structure Types: Nested message types with multiple fields
  • Custom Defined Types: Feature-specific types defined in FDL

Architecture & Components

Component Overview

┌─────────────────────────────────────────────────────────────┐
│                    Client Application                       │
└───────────────────────────┬─────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│              IDynamicMessageService                         │
│  - GetUnobservableProperty()                                │
│  - SubcribeObservableProperty()                             │
│  - ExecuteUnobservableCommand()                             │
│  - ExecuteObservableCommand()                               │
│  - GetObservableCommandResult()                             │
└───────────────────────────┬─────────────────────────────────┘
                            │
            ┌───────────────┴───────────────┐
            ▼                               ▼
┌─────────────────────┐         ┌─────────────────────┐
│   IPayloadFactory   │         │  protobuf-net       │
│                     │         │  GrpcClient         │
│ - Generates request │         │                     │
│   and response      │         │ - Reflection-based  │
│   types from FDL    │         │   method invocation │
└──────────┬──────────┘         └─────────────────────┘
           │
           ▼
┌─────────────────────────────────────────────────────────────┐
│           DynamicProtobufTypeBuilder                        │
│  - IL Emission-based type generation                        │
│  - Creates ProtoContract-decorated classes                  │
│  - Manages type caching in shared ModuleBuilder             │
└─────────────────────────────────────────────────────────────┘

DynamicProtobufTypeBuilder

Purpose: Generates .NET types at runtime using IL emission that are compatible with protobuf-net serialization.

Key Features:

  • Creates classes decorated with [ProtoContract] attribute
  • Generates properties with [ProtoMember(n)] attributes
  • Implements proper getter/setter IL instructions
  • Caches types in shared ModuleBuilder to avoid duplicates

Thread Safety: Type building uses a shared ModuleBuilder. The builder checks for existing types before creating new ones, but callers should implement locking if concurrent type generation for the same type name is possible.

PayloadFactory

Purpose: Analyzes SiLA2 FDL metadata to determine the correct .NET types for command parameters and property values.

Key Features:

  • Parses FDL XML to extract data type information
  • Maps SiLA2 data types to protobuf-net types
  • Handles complex types (lists, structures, constraints)
  • Generates separate request and response types
  • Supports metadata-affected properties (FCPAffectedByMetadata_* pattern)

Type Naming Convention:

  • Commands: {FeatureIdentifier}_{CommandIdentifier}_DynamicProtobufRequest/Response
  • Properties: {FeatureIdentifier}_{PropertyIdentifier}_DynamicProtobufRequest/Response
  • Intermediate Responses: {CommandIdentifier}_IntermediateResponses

DynamicMessageService

Purpose: Provides the main API for invoking SiLA2 operations using dynamically-generated types.

Key Features:

  • Uses protobuf-net's GrpcClient for code-first gRPC
  • Reflection-based method invocation for generic gRPC calls
  • Handles all four SiLA2 operation patterns
  • Constructs request messages from dictionaries
  • Returns responses as dynamically-typed objects

Performance Consideration: Uses reflection to invoke generic methods, which has overhead compared to compile-time generated stubs. For high-throughput scenarios, consider the standard approach.

ProtobufMarshaller

Purpose: Bridges between gRPC and protobuf-net serialization for dynamic types.

Key Features:

  • Provides Marshaller<T> instances for gRPC transmission
  • Delegates to ByteSerializer for protobuf serialization
  • Compatible with protobuf-net's serialization requirements
  • Supports custom serialization logic via ByteSerializer<T>

Usage Examples

Setup

All examples assume you have:

  1. A running SiLA2 server
  2. The feature definition (.sila.xml file)
  3. A gRPC channel connected to the server
using SiLA2.Communication.Services;
using SiLA2.Server.Utils;
using Grpc.Net.Client;

// Load feature definition
var feature = FeatureGenerator.ReadFeatureFromFile("TemperatureController-v1_0.sila.xml");

// Create gRPC channel
var channel = GrpcChannel.ForAddress("https://localhost:5001");

// Initialize dynamic message service
var dynamicMessageService = new DynamicMessageService(
    new PayloadFactory(new DynamicAssemblyBuilder()));

Example 1: Reading an Unobservable Property

// Read device status (returns immediately)
var response = dynamicMessageService.GetUnobservableProperty(
    propertyName: "DeviceStatus",
    channel: channel,
    feature: feature);

// Extract the value using reflection
var statusProperty = response.GetType().GetProperty("DeviceStatus").GetValue(response, null);
var statusValue = statusProperty.GetType().GetProperty("Value").GetValue(statusProperty, null);

Console.WriteLine($"Device Status: {statusValue}");

Note: The response is a dynamically-typed object. You need to use reflection to extract property values, or cast to the appropriate SiLA2 basic type if known.

Example 2: Subscribing to an Observable Property

// Subscribe to continuous temperature updates
var temperatureStream = dynamicMessageService.SubcribeObservableProperty(
    propertyName: "CurrentTemperature",
    channel: channel,
    feature: feature);

// Process streaming updates
await foreach (var update in temperatureStream)
{
    var tempProperty = update.GetType().GetProperty("CurrentTemperature").GetValue(update, null);
    var tempValue = ((Sila2.Org.Silastandard.Protobuf.Real)tempProperty).Value;

    Console.WriteLine($"Temperature: {tempValue}°C");

    // Cancel subscription after some condition
    if (tempValue > 100.0)
        break;
}

Cancellation: Use a CancellationToken in the foreach loop or break to stop receiving updates.

Example 3: Executing an Unobservable Command

using Sila2.Org.Silastandard.Protobuf;

// Prepare command parameters
var parameters = new Dictionary<string, object>
{
    { "Temperature", new Real { Value = 25.5 } },
    { "Unit", new String { Value = "Celsius" } }
};

// Execute command (returns immediately)
var response = dynamicMessageService.ExecuteUnobservableCommand(
    operationName: "SetTemperature",
    channel: channel,
    feature: feature,
    payloadMap: parameters);

// Check response (if command has return values)
if (response != null)
{
    var successProperty = response.GetType().GetProperty("Success");
    if (successProperty != null)
    {
        var success = ((Boolean)successProperty.GetValue(response, null)).Value;
        Console.WriteLine($"Command executed: {success}");
    }
}

Parameters: Use the SiLA2 protobuf types from Sila2.Org.Silastandard.Protobuf namespace. Parameter names must match identifiers in the FDL exactly.

Example 4: Executing an Observable Command with Progress Tracking

using Sila2.Org.Silastandard;
using Sila2.Org.Silastandard.Protobuf;

// Prepare command parameters
var parameters = new Dictionary<string, object>
{
    { "TargetTemperature", new Real { Value = 80.0 } },
    { "Duration", new Real { Value = 300.0 } } // 5 minutes
};

// Initiate observable command
var result = dynamicMessageService.ExecuteObservableCommand(
    operationName: "StartHeating",
    channel: channel,
    feature: feature,
    payloadMap: parameters);

var commandConfirmation = result.Item1;
var executionInfoStream = result.Item2;
var intermediateStream = result.Item3;  // null if no intermediate responses
var responseType = result.Item4;

Console.WriteLine($"Command initiated: {commandConfirmation.CommandExecutionUUID.Value}");

// Monitor execution progress
await foreach (var executionInfo in executionInfoStream)
{
    Console.WriteLine($"Status: {executionInfo.CommandStatus}");
    Console.WriteLine($"Progress: {executionInfo.ProgressInfo?.Value * 100:F1}%");

    if (executionInfo.CommandStatus == ExecutionInfo.Types.CommandStatus.FinishedSuccessfully)
    {
        Console.WriteLine("Command completed successfully!");
        break;
    }
    else if (executionInfo.CommandStatus == ExecutionInfo.Types.CommandStatus.FinishedWithError)
    {
        Console.WriteLine($"Command failed: {executionInfo.Message?.Value}");
        break;
    }
}

// Retrieve final result
var finalResult = dynamicMessageService.GetObservableCommandResult(
    cmdId: commandConfirmation.CommandExecutionUUID,
    operationName: "StartHeating",
    channel: channel,
    feature: feature,
    responseType: responseType);

// Extract result values
var finalTemp = finalResult.GetType().GetProperty("FinalTemperature");
if (finalTemp != null)
{
    var temp = ((Real)finalTemp.GetValue(finalResult, null)).Value;
    Console.WriteLine($"Final temperature: {temp}°C");
}

Example 5: Handling Intermediate Responses

// For commands that define IntermediateResponse in FDL
var result = dynamicMessageService.ExecuteObservableCommand(
    operationName: "RunExperiment",
    channel: channel,
    feature: feature,
    payloadMap: parameters);

var executionInfoStream = result.Item2;
var intermediateStream = result.Item3;

// Process intermediate responses in parallel with execution info
var intermediateTask = Task.Run(async () =>
{
    if (intermediateStream != null)
    {
        await foreach (var intermediate in intermediateStream)
        {
            // Extract intermediate data (structure depends on FDL definition)
            var currentReading = intermediate.GetType()
                .GetProperty("CurrentReading")?.GetValue(intermediate, null);

            if (currentReading != null)
            {
                var reading = ((Real)currentReading).Value;
                Console.WriteLine($"Intermediate reading: {reading}");
            }
        }
    }
});

// Monitor execution status
await foreach (var executionInfo in executionInfoStream)
{
    if (executionInfo.CommandStatus == ExecutionInfo.Types.CommandStatus.FinishedSuccessfully ||
        executionInfo.CommandStatus == ExecutionInfo.Types.CommandStatus.FinishedWithError)
    {
        break;
    }
}

// Wait for intermediate task to complete
await intermediateTask;

// Get final result
var finalResult = dynamicMessageService.GetObservableCommandResult(
    result.Item1.CommandExecutionUUID,
    "RunExperiment",
    channel,
    feature,
    result.Item4);

Advanced Topics

Handling Complex Data Types

Structure Types

Structures in SiLA2 are nested message types:

// FDL defines a structure like:
// <StructureType>
//   <Element>
//     <Identifier>X</Identifier>
//     <DataType><Basic>Real</Basic></DataType>
//   </Element>
//   <Element>
//     <Identifier>Y</Identifier>
//     <DataType><Basic>Real</Basic></DataType>
//   </Element>
// </StructureType>

// Create structure instance dynamically
var structureType = Type.GetType("DynamicallyGenerated_CoordinateStructure");
var structureInstance = Activator.CreateInstance(structureType);

// Set nested properties
var xProperty = structureInstance.GetType().GetProperty("X");
xProperty.SetValue(structureInstance, new Real { Value = 10.5 });

var yProperty = structureInstance.GetType().GetProperty("Y");
yProperty.SetValue(structureInstance, new Real { Value = 20.3 });

// Use in command parameters
var parameters = new Dictionary<string, object>
{
    { "Position", structureInstance }
};
List Types

Lists use Google.Protobuf.Collections.RepeatedField<T>:

using Google.Protobuf.Collections;
using Sila2.Org.Silastandard.Protobuf;

// Create a list of strings
var stringList = new RepeatedField<String>();
stringList.Add(new String { Value = "First" });
stringList.Add(new String { Value = "Second" });
stringList.Add(new String { Value = "Third" });

var parameters = new Dictionary<string, object>
{
    { "Names", stringList }
};

var response = dynamicMessageService.ExecuteUnobservableCommand(
    "ProcessNames", channel, feature, parameters);
Constrained Types

Constrained types (e.g., Real with min/max) are handled transparently:

// FDL defines constraint: <MinimalInclusive>0</MinimalInclusive>
// The PayloadFactory resolves this to the underlying Real type

var parameters = new Dictionary<string, object>
{
    { "Speed", new Real { Value = 50.0 } }  // Constraint validation happens server-side
};

Metadata-Affected Properties

SiLA2 features can define metadata that affects which commands/properties are available. The package supports the FCPAffectedByMetadata_{MetadataIdentifier} pattern:

// Get list of calls affected by specific metadata
var response = dynamicMessageService.GetUnobservableProperty(
    propertyName: "FCPAffectedByMetadata_StringMetadata",
    channel: channel,
    feature: feature);

// Extract affected calls list
var affectedCallsProperty = response.GetType().GetProperty("AffectedCalls");
var affectedCalls = (Google.Protobuf.Collections.RepeatedField<String>)affectedCallsProperty.GetValue(response);

foreach (var call in affectedCalls)
{
    Console.WriteLine($"Affected call: {call.Value}");
}

Custom Data Type Resolution

For features with custom defined data types in FDL:

<DataTypeDefinition>
  <Identifier>Temperature</Identifier>
  <DataType>
    <Constrained>
      <DataType><Basic>Real</Basic></DataType>
      <Constraints>
        <MinimalInclusive>-273.15</MinimalInclusive>
        <MaximalInclusive>1000.0</MaximalInclusive>
      </Constraints>
    </Constrained>
  </DataType>
</DataTypeDefinition>

The PayloadFactory automatically resolves custom types by traversing the FDL definition tree:

// Usage is transparent - just use the parameter name
var parameters = new Dictionary<string, object>
{
    { "SetPoint", new Real { Value = 25.0 } }  // Temperature type resolved to Real
};

Thread Safety Considerations

ModuleBuilder Caching: The DynamicProtobufTypeBuilder uses a shared ModuleBuilder for type generation. While type definition operations are thread-safe, checking for existing types is not atomic.

Recommendation: For multi-threaded scenarios where the same feature might be loaded concurrently, implement a locking strategy around feature initialization:

private static readonly SemaphoreSlim _featureLoadLock = new SemaphoreSlim(1, 1);
private static readonly Dictionary<string, Feature> _featureCache = new();

public async Task<Feature> LoadFeatureAsync(string featurePath)
{
    await _featureLoadLock.WaitAsync();
    try
    {
        if (!_featureCache.ContainsKey(featurePath))
        {
            var feature = FeatureGenerator.ReadFeatureFromFile(featurePath);
            _featureCache[featurePath] = feature;
        }
        return _featureCache[featurePath];
    }
    finally
    {
        _featureLoadLock.Release();
    }
}

Error Handling Patterns

using Grpc.Core;

try
{
    var response = dynamicMessageService.ExecuteUnobservableCommand(
        "SetTemperature", channel, feature, parameters);
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.InvalidArgument)
{
    // SiLA2 validation error (e.g., parameter constraint violation)
    Console.WriteLine($"Validation error: {ex.Status.Detail}");
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.FailedPrecondition)
{
    // SiLA2 defined execution error
    Console.WriteLine($"Execution error: {ex.Status.Detail}");

    // Parse SiLA2 error details from metadata
    var errorType = ex.Trailers.GetValue("sila2-error-type");
    var errorIdentifier = ex.Trailers.GetValue("sila2-error-identifier");
}
catch (RpcException ex)
{
    // Other gRPC errors (network, authentication, etc.)
    Console.WriteLine($"gRPC error: {ex.StatusCode} - {ex.Status.Detail}");
}
catch (ArgumentException ex)
{
    // Invalid property/command name or parameter
    Console.WriteLine($"Invalid parameter: {ex.Message}");
}

Comparison with Standard Approach

Aspect SiLA2.Communication (Dynamic) Standard XSLT/protoc
Setup Time Instant (load FDL at runtime) Requires build step
Flexibility Load any feature dynamically Must recompile for new features
Performance Slower (reflection overhead) Faster (compiled code)
Type Safety Runtime checks only Compile-time type checking
Code Completion Limited (dynamic types) Full IntelliSense support
Binary Size Smaller (no generated code) Larger (generated assemblies)
Use Case Universal clients, testing Production feature implementations
Debugging More complex (reflection) Standard debugging
Maintenance No code generation to maintain MSBuild targets required

Performance Benchmark (approximate):

  • Standard approach: ~0.5ms per call overhead
  • Dynamic approach: ~2-5ms per call overhead (varies with complexity)

For most SiLA2 operations (which involve I/O, device communication, etc.), this overhead is negligible compared to the operation duration.

API Reference Summary

IDynamicMessageService

Main interface for dynamic SiLA2 communication.

public interface IDynamicMessageService
{
    // Unobservable property access
    object GetUnobservableProperty(
        string propertyName,
        GrpcChannel channel,
        Feature feature,
        Grpc.Core.Metadata metadata = null);

    // Observable property subscription
    IAsyncEnumerable<object> SubcribeObservableProperty(
        string propertyName,
        GrpcChannel channel,
        Feature feature,
        Grpc.Core.Metadata metadata = null);

    // Unobservable command execution
    object ExecuteUnobservableCommand(
        string operationName,
        GrpcChannel channel,
        Feature feature,
        IDictionary<string, object> payloadMap = null,
        Grpc.Core.Metadata metadata = null);

    // Observable command initiation
    Tuple<CommandConfirmation, IAsyncEnumerable<ExecutionInfo>,
          IAsyncEnumerable<object>, Type> ExecuteObservableCommand(
        string operationName,
        GrpcChannel channel,
        Feature feature,
        IDictionary<string, object> payloadMap = null,
        Grpc.Core.Metadata metadata = null);

    // Observable command result retrieval
    object GetObservableCommandResult(
        CommandExecutionUUID cmdId,
        string operationName,
        GrpcChannel channel,
        Feature feature,
        Type responseType,
        Grpc.Core.Metadata metadata = null);
}

IPayloadFactory

Interface for generating dynamic protobuf types from FDL metadata.

public interface IPayloadFactory
{
    // Command payload types (request and response)
    Tuple<Type, Type> GetCommandPayloadTypes(
        Feature feature,
        string operation);

    // Observable command with intermediate responses
    Tuple<Type, Type, Type> GetCommandPayloadTypesWithIntermediateCommandResponseType(
        Feature feature,
        string operation);

    // Property payload types
    Tuple<Type, Type> GetPropertyPayloadTypes(
        Feature feature,
        string property);
}

IDynamicAssemblyBuilder

Provides shared ModuleBuilder for type caching.

public interface IDynamicAssemblyBuilder
{
    ModuleBuilder ModuleBuilder { get; }
}

Contributing & Development

This package is part of the sila_csharp project.

Building from Source

git clone --recurse-submodules https://gitlab.com/SiLA2/sila_csharp.git
cd sila_csharp/src
dotnet build SiLA2.Communication/SiLA2.Communication.csproj

Running Tests

dotnet test Tests/SiLA2.Communication.Tests/SiLA2.Communication.Tests.csproj
dotnet test Tests/SiLA2.IntegrationTests.Server.Tests/SiLA2.IntegrationTests.Server.Tests.csproj --filter "FullyQualifiedName~DynamicClient"

Project Structure

SiLA2.Communication/
├── Protobuf/
│   ├── DynamicProtobufTypeBuilder.cs  # IL emission-based type generation
│   ├── ProtobufMarshaller.cs          # gRPC marshalling for dynamic types
│   └── ByteSerializer.cs              # protobuf-net serialization
├── Services/
│   ├── DynamicMessageService.cs       # Main gRPC client implementation
│   ├── PayloadFactory.cs              # FDL-to-Type mapper
│   ├── DynamicAssemblyBuilder.cs      # Shared ModuleBuilder provider
│   └── Interfaces/
└── SiLA2FrameworkEntities.cs          # SiLA2 base protobuf types

License

This project is licensed under the MIT License.

Maintainer

Christoph Pohl (@Chamundi)

Security

For security vulnerabilities, please refer to the SiLA2 Vulnerability Policy.


Questions or Issues?

  • Open an issue on GitLab
  • Join the SiLA community on Slack
  • Check the Wiki for additional documentation
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on SiLA2.Communication:

Package Downloads
SiLA2.Frontend.Razor

Web Frontend Extension for SiLA2.Server Package

SiLA2.Client.Dynamic

SiLA2.Client.Dynamic Package

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.2.2 40 2/12/2026
10.2.1 115 1/25/2026
10.2.0 315 12/23/2025
10.1.0 524 11/29/2025
10.0.0 946 11/11/2025
9.0.4 1,226 6/25/2025
9.0.3 1,167 6/21/2025
9.0.2 1,219 1/6/2025
9.0.1 1,211 11/17/2024
9.0.0 1,216 11/13/2024
8.1.2 1,255 10/20/2024
8.1.1 1,314 8/31/2024
8.1.0 1,886 2/11/2024
8.0.0 1,645 11/15/2023
7.5.4 1,292 10/27/2023
7.5.3 1,455 7/19/2023
7.5.2 1,385 7/4/2023