ECP.DependencyInjection
2.0.5
Prefix Reserved
dotnet add package ECP.DependencyInjection --version 2.0.5
NuGet\Install-Package ECP.DependencyInjection -Version 2.0.5
<PackageReference Include="ECP.DependencyInjection" Version="2.0.5" />
<PackageVersion Include="ECP.DependencyInjection" Version="2.0.5" />
<PackageReference Include="ECP.DependencyInjection" />
paket add ECP.DependencyInjection --version 2.0.5
#r "nuget: ECP.DependencyInjection, 2.0.5"
#:package ECP.DependencyInjection@2.0.5
#addin nuget:?package=ECP.DependencyInjection&version=2.0.5
#tool nuget:?package=ECP.DependencyInjection&version=2.0.5
ECP — Emergency Communication Protocol
A binary protocol for emergency communications.
Table of contents
- Safety-Critical Use Notice
- What is ECP?
- Quick start
- Choose your level of control
- Packages
- Package examples
- Dependency injection
- Benchmarks
- Measured results
- Capabilities
- Privacy
- Versioning
- Patent and license
- Security
- Export notice
- Resources
Safety-Critical Use Notice
ECP is provided under Apache-2.0 on an "AS IS" basis and is not warranted to be error-free. ECP is not developed, tested, or certified as a standalone safety mechanism for life-safety systems. Users and integrators are solely responsible for system-level hazard analysis, validation, certification, and compliance with applicable laws and standards before operational deployment. See also NOTICE for additional legal and safety notices.
What is ECP?
ECP encodes emergency alerts into compact binary messages — from 8 to 100 bytes — with built-in cryptographic integrity. It was designed for scenarios where bandwidth is limited, latency matters, and message authenticity cannot be optional.
Size comparison
| Format | Alert size | Notes |
|---|---|---|
| CAP XML (OASIS) | 669 bytes | Industry standard for alerting |
| JSON over HTTP | 270 bytes | Common in web applications |
| ECP Envelope | 45–100 bytes | Binary, signed, with metadata |
| ECP Token (UET) | 8 bytes | Minimal alert, no payload |
These numbers are reproducible. Public benchmarks are available in benchmarks/ so you can measure them yourself.
During testing, ECP has processed 141,000+ real events with an average data reduction of 96%. We publish these numbers for transparency — reproducible verification artifacts are available in test-vectors/ and tests/. See the Measured results section.
Quick start
Install
dotnet add package ECP.Core
Send your first alert
using ECP.Core;
using ECP.Core.Models;
byte[] alert = Ecp.Alert(EmergencyType.Fire, zoneHash: 1, priority: EcpPriority.Critical);
That's it. alert contains the emergency type, priority, zone, timestamp, and action flags in 8 bytes.
Choose your level of control
ECP has a progressive API. Start simple, add control when you need it.
Level 1 — One-liner
using ECP.Core;
using ECP.Core.Models;
byte[] alert = Ecp.Alert(EmergencyType.Earthquake, zoneHash: 42, priority: EcpPriority.Critical);
// 8 bytes, done.
Level 2 — Token (structured access)
using ECP.Core;
using ECP.Core.Models;
var token = Ecp.Token(
EmergencyType.Fire,
EcpPriority.Critical,
ActionFlags.SoundAlarm | ActionFlags.FlashLights);
byte[] bytes = token.ToBytes(); // 8 bytes
string base64 = token.ToBase64(); // 12 chars — fits in an SMS
Level 3 — Envelope (full protocol)
using ECP.Core;
using ECP.Core.Models;
byte[] hmacKey = new byte[32]; // your HMAC-SHA256 key (32 bytes recommended)
var envelope = Ecp.Envelope()
.WithType(EmergencyType.Earthquake)
.WithPriority(EcpPriority.Critical)
.WithTtl(120)
.WithPayload("Evacuate Building A via Stairway B")
.WithHmacKey(hmacKey)
.Build();
byte[] wire = envelope.ToBytes(); // 45–100 bytes, signed, verified
Level 4 — Zero allocation (high throughput)
using ECP.Core;
using ECP.Core.Models;
using ECP.Core.Token;
var token = Ecp.Token(EmergencyType.Fire, EcpPriority.Critical);
Span<byte> buffer = stackalloc byte[UniversalEmergencyToken.Size]; // 8 bytes
token.WriteTo(buffer);
// 0.28 ns, zero heap allocation
Decode from any source
using ECP.Core;
using ECP.Core.Models;
byte[] incomingBytes = GetIncomingBytes();
if (Ecp.TryDecode(incomingBytes, out var message))
{
if (message.IsUet)
{
System.Console.WriteLine($"Type: {message.Token.EmergencyType}, Priority: {message.Token.Priority}");
}
else if (message.IsEnvelope)
{
System.Console.WriteLine($"Envelope payload type: {message.Envelope.PayloadType}");
}
}
static byte[] GetIncomingBytes() => System.Array.Empty<byte>();
Packages
| Package | Tier | What it does | When to use it |
|---|---|---|---|
ECP.Core |
Free (Apache-2.0) | Protocol encoder/decoder, UET, Envelope, security | Start here. Works everywhere. |
ECP.Standard |
Free (Apache-2.0) | Core + Registry + Cascade + DI helpers | Full-featured applications |
ECP.Registry |
Free (Apache-2.0) | Semantic compression, multilingual templates | When you need smaller payloads |
ECP.Cascade |
Free (Apache-2.0) | P2P broadcast, adaptive fan-out, confirmations | Multi-node delivery |
ECP.DependencyInjection |
Free (Apache-2.0) | AddEcpCore() for .NET DI |
ASP.NET Core / hosted services |
ECP.Transport.Abstractions |
Free (Apache-2.0) | Transport layer interfaces | Building custom transports |
ECP.Transport.WebSocket |
Free (Apache-2.0) | WebSocket transport | Real-time web delivery |
ECP.Transport.SignalR |
Free (Apache-2.0) | SignalR transport | ASP.NET Core SignalR |
ECP.Compatibility |
Free (Apache-2.0) | JSON-to-ECP bridge | Migrating from JSON APIs |
ECP.Offline |
Premium (commercial) | Offline activation, deterministic authorization, forensic chain integration | Enterprise offline and compliance scenarios |
ECP.Diagnostics.Enterprise (planned) |
Premium (commercial) | Advanced diagnostics and governance/compliance tooling | Large-scale operations and audit programs |
Naming note: Cascade is a public package name for multi-node propagation and confirmation behavior.
Which package do I need?
- Embedded device / IoT / BLE? →
ECP.Core(zero dependencies) - ASP.NET Core application? →
ECP.Standard+ECP.DependencyInjection - Migrating from JSON? → Add
ECP.Compatibility - Offline authorization / forensic evidence? →
ECP.Offline(commercial license)
Package examples
ECP.Core and ECP.Standard already have examples above. This section covers the other free packages with copy/paste snippets.
ECP.Registry — explicit default dictionary parameters
using System.Text;
using ECP.Registry.Dictionary;
var dictionary = EmergencyDictionary.CreateDefault(dictionaryId: 1, dictionaryVersion: 1);
byte[] input = Encoding.UTF8.GetBytes("immediate evacuation at Gate B2");
Span<byte> compressed = stackalloc byte[128];
dictionary.TryCompress(input, compressed, out int compressedLength);
Span<byte> restored = stackalloc byte[128];
dictionary.TryDecompress(compressed[..compressedLength], restored, out int restoredLength);
string text = Encoding.UTF8.GetString(restored[..restoredLength]);
ECP.Cascade — trust score and fan-out limit
using ECP.Cascade;
var trust = new TrustScoreService();
int defaultScore = trust.GetScore("node-alpha"); // 55 by default
trust.SetScore("node-alpha", 82);
int score = trust.GetScore("node-alpha");
int fanOut = trust.GetFanOutLimit("node-alpha"); // high tier => wider propagation
ECP.Compatibility — full JsonBridge.ToEcp signature
using ECP.Compatibility;
using ECP.Core.Models;
byte[] hmacKey = new byte[32];
string legacyJson = """{"payloadText":"Evacuate terminal 3 via stairway B","ttl":90}""";
byte[] ecpBytes = JsonBridge.ToEcp(
legacyJson,
hmacKey.AsSpan(),
hmacLength: 16, // valid range: 8-16 (or 0 to disable HMAC)
keyVersion: 1,
priority: EcpPriority.Critical,
ttlSeconds: 120,
flags: EcpFlags.None,
payloadType: EcpPayloadType.Alert);
ECP.DependencyInjection — AddEcpCore registration output
using System.Linq;
using ECP.Core.Security;
using ECP.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
byte[] hmacKey = new byte[32];
var services = new ServiceCollection();
var keyRing = new KeyRing();
keyRing.AddKey(1, hmacKey);
services.AddEcpCore(o => { o.HmacLength = 16; o.KeyVersion = 1; o.KeyProvider = keyRing; });
string[] registered = services.Select(d => d.ServiceType.FullName!).OrderBy(n => n).ToArray();
Console.WriteLine($"AddEcpCore registered {registered.Length} services.");
With a KeyRing provider, AddEcpCore() registers these 7 services:
ECP.Core.EcpOptionsECP.Core.Security.IKeyProviderECP.Core.Security.ITenantKeyProviderECP.Core.Tenancy.ITenantContextECP.Core.Privacy.ITenantPrivacyOptionsProviderECP.Core.Privacy.ZoneHashProviderECP.Core.Strategy.IStrategySelector
ECP.Transport.Abstractions — transport-agnostic send flow
using ECP.Transport.Abstractions;
static async Task SendAlertAsync(IEcpTransport transport, byte[] packet, CancellationToken ct)
{
if (!transport.IsConnected)
{
await transport.ConnectAsync("wss://alerts.example/ws", ct);
}
await transport.SendAsync(packet, ct);
}
ECP.Transport.WebSocket — constructor and ConnectAsync endpoint
using System.Threading;
using ECP.Core.Security;
using ECP.Core;
using ECP.Transport.WebSocket;
byte[] hmacKey = new byte[32];
var keyRing = new KeyRing();
keyRing.AddKey(1, hmacKey);
await using var transport = new EcpWebSocketTransport(
new EcpWebSocketOptions(),
new EcpOptions { HmacLength = 16, KeyVersion = 1, KeyProvider = keyRing },
keyRing);
string endpoint = "wss://alerts.example/ws";
var connect = (CancellationToken ct) => transport.ConnectAsync(endpoint, ct); // endpoint belongs here
ECP.Transport.SignalR — constructor and ConnectAsync endpoint
using System.Threading;
using ECP.Core.Security;
using ECP.Core;
using ECP.Transport.SignalR;
byte[] hmacKey = new byte[32];
var keyRing = new KeyRing();
keyRing.AddKey(1, hmacKey);
await using var transport = new EcpSignalRTransport(
new EcpSignalROptions(),
new EcpOptions { HmacLength = 16, KeyVersion = 1, KeyProvider = keyRing },
keyRing);
string endpoint = "https://alerts.example/hubs/ecp";
var connect = (CancellationToken ct) => transport.ConnectAsync(endpoint, ct); // endpoint belongs here
Dependency injection
Minimal setup (Core only)
using ECP.Core;
using ECP.Core.Security;
using ECP.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
byte[] hmacKey = new byte[32]; // load your key from secure storage
var keyRing = new KeyRing();
keyRing.AddKey(keyVersion: 1, key: hmacKey);
builder.Services.AddEcpCore(options =>
{
options.HmacLength = 16;
options.KeyVersion = 1;
options.KeyProvider = keyRing;
});
Full setup (Core + Registry + Cascade)
using ECP.Core;
using ECP.Core.Security;
using ECP.Standard;
var builder = WebApplication.CreateBuilder(args);
byte[] hmacKey = new byte[32]; // load your key from secure storage
var keyRing = new KeyRing();
keyRing.AddKey(keyVersion: 1, key: hmacKey);
builder.Services.AddEcpStandard(options =>
{
options.HmacLength = 16;
options.KeyVersion = 1;
options.KeyProvider = keyRing;
});
Preset profiles
using ECP.Core.Profiles;
using ECP.Standard;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEcpProfile(EcpProfile.Minimal); // Core only
builder.Services.AddEcpProfile(EcpProfile.Enterprise); // Core + Registry + Cascade
Benchmarks
Run with BenchmarkDotNet on .NET 8.0.
Environment: 13th Gen Intel(R) Core(TM) i9-13900KF, .NET SDK 8.0.418 (Microsoft.NETCore.App 8.0.24), Release configuration, RyuJIT x64. Full details and runnable code are in benchmarks/.
| Operation | Time | Allocation |
|---|---|---|
| UET Encode | 3.3 ns | 32 B |
| UET Encode (zero-alloc) | 0.28 ns | 0 B |
| UET Decode | 1.2 ns | 0 B |
| Envelope Build + Encode | 334 ns | 416 B |
| Envelope Encode (zero-alloc) | 6.5 ns | 0 B |
| Envelope Decode + HMAC verify | 262 ns | 0 B |
At 262 ns per decode, a single core can process roughly 3.8 million messages per second. Most of that time (~250 ns) is spent on HMAC-SHA256 verification — a deliberate choice to keep integrity verification on by default.
Runnable benchmark code is available in benchmarks/ so you can reproduce these numbers on your own hardware. If your measurements differ significantly, please open an issue. We want these numbers to be honest.
Measured results
These numbers come from testing with real event data. We share them for transparency.
Test vectors and source tests are available in test-vectors/ and tests/ so you can verify protocol behavior independently.
| Metric | Value |
|---|---|
| Real events processed | 141,000+ |
| Average data reduction | 96% |
| Forensic records verified | 645 |
| Delivery confirmations tracked | 182 |
| Automated tests (SDK, private CI) | 235 |
| Public test projects | 10 |
We're a small team and this is a young protocol. If you find issues, inconsistencies, or have questions about these numbers, we genuinely want to hear from you.
Capabilities
- 8-byte alerts — UET format encodes a complete emergency in 8 bytes
- Zero dependencies — Core uses only .NET BCL, no external packages
- Transport agnostic — Tested over WebSocket; designed for BLE, LoRa, SMS, satellite, NFC
- Built-in security — HMAC-SHA256 authentication, AES-GCM encryption (optional)
- Zero-allocation paths —
WriteTo(Span<byte>)for constrained environments - Cascade broadcast — P2P delivery, O(log N) scaling, confirmation aggregation
- Forensic integrity (premium) — Tamper-evident records for enterprise deployments (patent pending)
- Offline activation (premium) — Deterministic activation flows for disconnected scenarios (patent pending)
- Semantic compression — Two-level dictionary (global + tenant)
- Progressive API — One-liner → Token → Builder → Zero-alloc, choose your level
Privacy
ECP-SDK does not collect, transmit, or store any data. No telemetry, no analytics, no network calls. The SDK runs entirely inside your application.
This design helps support compliance with regulations such as GDPR, HIPAA, and similar frameworks, depending on your system integration.
Versioning
ECP follows Semantic Versioning:
- PATCH — Bug fixes, no API changes
- MINOR — New features, backward compatible
- MAJOR — Breaking changes (with migration guide)
Public APIs marked [Obsolete] are maintained for at least one minor version before removal.
Patent and license
ECP uses an Open Core model.
Free packages (Apache-2.0): The packages listed as "Free" in this README are licensed under Apache 2.0 and can be used in development and production, including commercial use.
Premium packages (commercial license): Premium modules (such as ECP.Offline and ECP.Diagnostics.Enterprise) require a separate commercial agreement. Contact licensing@egonex-group.com.
ECP technology includes patent-pending elements filed with UIBM. For Apache-licensed packages, patent rights (if any) are granted only as stated in Section 3 of Apache License 2.0.
See LICENSE.txt and NOTICE for legal terms and attribution notices.
Security
Found a vulnerability? Do not open a public issue. See SECURITY.md for our responsible disclosure policy.
Export notice
This software uses standard cryptographic algorithms (AES-GCM, HMAC-SHA256) provided by the .NET runtime. It does not implement custom cryptographic primitives. Distribution of this software may be subject to export control regulations in certain jurisdictions.
Resources
In this repository:
- Wire format specification
- Source code — free package implementations published in this repository
- Samples — 8 runnable console applications
- Benchmarks — BenchmarkDotNet project, reproducible
- Tests — 10 public test projects
- Test vectors — deterministic JSON vectors for cross-platform verification
- Changelog
- Contributing
- Security policy
External:
Made in Italy by Egonex S.R.L. — built for emergencies, open source for builders.
Copyright © 2026 Egonex S.R.L.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net8.0
- ECP.Core (>= 2.0.5)
- Microsoft.Extensions.DependencyInjection (>= 8.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on ECP.DependencyInjection:
| Package | Downloads |
|---|---|
|
ECP.Standard
Full-stack distribution that bundles Core, Registry, Cascade, and DI setup. Use one reference to enable encoding, compression, adaptive broadcast, and service registration. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.5 | 57 | 3/12/2026 |