Zum Hauptinhalt springen

CK Language 2

CK Language 2 ist eine Opt-in-Erweiterung der Construction-Kit-YAML-Sprache. Ein Modell, das ckLanguage: 2 in seiner ckModel.yaml deklariert, kann Folgendes verwenden:

  • Interfaces — versionierte Verträge (Named-1) mit Attribut-, Assoziations- und Methoden-Membern, die Typen implementieren;
  • Zugriffsmodifikatoren — visibility und derivable an Elementen, access an Attributzuweisungen (einschließlich Hidden);
  • Methodendefinitionen — typisierte Methodensignaturen an Typen und Interfaces (nur Definitionen; siehe Status);
  • strengere Standardwerte: Typen und Records eines v2-Modells können nur innerhalb ihres eigenen Modells abgeleitet werden, sofern sie nichts anderes angeben.

Ein Modell ohne ckLanguage ist ein CK-Language-1-Modell. Es wird exakt wie bisher kompiliert — Byte für Byte — und behält seine Semantik: Alles ist öffentlich und ableitbar, es gibt keine Interfaces und keine Methoden.

Verfügbarkeit

CK Language 2 benötigt die CK-v2-Engine (minEngineVersion 3.5.1, siehe Engine- und Katalog-Guard). Sie wird phasenweise eingeführt; diese Seite beschreibt, was heute verfügbar ist. Importieren Sie ein ckLanguage: 2-Modell erst dann in eine Umgebung, wenn jeder dortige Dienst die CK-v2-Engine ausführt — ältere Engines ignorieren die neuen Schlüssel und würden beispielsweise Hidden-Attribute offenlegen.

Betriebsregel: gemeinsame Kataloge

Veröffentlichen Sie keine ckLanguage: 2- oder Range-Retention-Version eines Basismodells (zum Beispiel System oder Basic) in einem gemeinsamen Katalog — den GitHub-Katalogen (octo-ckc) oder jedem Katalog, gegen den andere Teams kompilieren —, bevor nicht jeder Dienst, der diesen Katalog nutzt, die CK-v2-Engine ausführt.

Kataloge listen die Versionen beider Wurzeln auf. Nach einer einzigen solchen Veröffentlichung löst jeder gegen den Katalog kompilierte Dependent die neue Basisversion auf, erbt deren minEngineVersion und wird unter ck-models/v3/ veröffentlicht — auch dann, wenn der Dependent selbst CK Language 1 ist. Ältere Engines sehen von all diesen Dependents weiterhin nur die älteren ck-models/v2/-Versionen. Evaluieren Sie CK Language 2 und Range Retention ausschließlich im lokalen Katalog.

Upgrade und Rollback​

Die Einführung der CK-v2-Engine erfordert keine Datenbankmigration und kein Update des System-Modells: Alle System-Modelle bleiben CK Language 1, neue Felder werden nur für CK-Language-2-Modelle geschrieben, und die neuen Collections (CkInterface, CkTypeInterfaceImplementation) werden beim nächsten Import angelegt, bleiben aber leer, bis ein CK-Language-2-Modell importiert wird. Ein Tenant, der bisher nur CK-Language-1-Importe gesehen hat, hat exakt dieselben Construction-Kit-Dokumente wie zuvor, sodass die Dienste auf die vorherige Engine zurückgerollt werden können. Nach dem ersten Import eines ckLanguage: 2-Modells (oder eines Range-Retention-Modells) in einen Tenant ist ein Rollback nicht mehr sicher.

Opt-in​

$schema: https://schemas.meshmakers.cloud/construction-kit-meta.schema.json
modelId: Acme.Assets-1.0.0
ckLanguage: 2
description: Example CK language 2 model
dependencies:
- System-[2.5,3.0)

ckLanguage akzeptiert 1 und 2; fehlt der Schlüssel, gilt 1. Jeder andere Wert in der Quelle ist ein Schemafehler (Meldung 27). Ein kompiliertes Modell, das eine Sprachversion deklariert, die die laufende Engine nicht unterstützt, wird abgelehnt — auch dann, wenn es nur eine Abhängigkeit ist: Der Compiler meldet Meldung 91; beim Import in einen Tenant ist die Ablehnung ein Importfehler mit demselben Text.

Jeder CK-Language-2-Schlüssel, der in einem Modell ohne ckLanguage: 2 verwendet wird, wird mit Meldung 90 abgelehnt:

Error 90 types/types.yaml: Model 'Acme.Plant-1.0.0' uses the CK v2 feature 'implements' at 'Acme.Plant-1.0.0/Pump-1',
which requires 'ckLanguage: 2' in ckModel.yaml (declared: 1).

Was sich mit ckLanguage: 2 ändert​

SchlüsselWoCK Language 1CK Language 2 (Standard, wenn nicht angegeben)
interfaces (Ordner interfaces/)Modellnicht erlaubt—
implementsTypnicht erlaubt[]
methodsTyp, Interfacenicht erlaubt[]
visibilityTyp, Record, Enum, Attribut, Assoziationsrolle, Interface, Methodenicht erlaubt (alles Public)Public
derivableTyp, Recordnicht erlaubt (alles Any)Model
accessAttributzuweisung an einem Typ, Record oder einer Assoziationsrollenicht erlaubt (ReadWrite)ReadWrite
targetCkInterfaceIdTyp-Assoziationnicht erlaubt—

Werte werden in PascalCase geschrieben (Public/Internal, Model/Any, ReadWrite/ReadOnly/MethodOnly/Hidden); Werte in Kleinbuchstaben sind Schemafehler.

Der Standardwert von derivable ist der wichtige Unterschied: In einem v2-Modell kann ein anderes Modell nur von einem Typ oder Record ableiten, der derivable: Any deklariert. Damit wird „Basisklasse für andere Modelle sein“ zu einer expliziten Entscheidung des Modellautors. Siehe derivable.

CK Language 1 und 2 mischen​

  • Ein v1-Modell kann von einem v2-Modell abhängen und umgekehrt.
  • Es gelten die Regeln des Modells, das ein Element deklariert. Ein v1-Modell, das von einem Typ einer v2-Abhängigkeit ableitet, wird weiterhin abgelehnt, wenn dieser Typ derivable: Model ist (Meldung 113), und es kann niemals auf ein Internal-Element davon verweisen (Meldung 112).
  • Ein v1-Modell kann selbst keine CK-Language-2-Schlüssel verwenden (Meldung 90) — um ein Interface einer Abhängigkeit zu implementieren, muss das Modell auf ckLanguage: 2 umgestellt werden.

Versionierungsfolge der Umstellung auf ckLanguage: 2​

Das Anheben von ckLanguage von 1 auf 2 ist für sich genommen eine Minor-Änderung. Da jedoch der Standardwert von derivable von Any auf Model wechselt, ist es eine Major-Änderung, sofern nicht jeder Typ und Record des Modells explizit derivable: Any deklariert. Das SemVer-Gate meldet dies als eine derivable-Änderung pro Element. Wenn Dependents Ihres Modells von dessen Typen ableiten, deklarieren Sie bei der Einführung von CK Language 2 derivable: Any genau an diesen Typen.

Engine- und Katalog-Guard​

Ältere Engines lesen kompilierte Modelle tolerant und würden Schlüssel, die sie nicht kennen (implements, access, visibility, ...), stillschweigend verwerfen. Zwei Mechanismen halten ein v2-Modell von ihnen fern:

  • minEngineVersion. Der Compiler schreibt minEngineVersion: 3.5.1 in jedes ckLanguage: 2-Modell und jedes Range-Retention-Modell. Ein CK-Language-1-Modell trägt normalerweise keine — es erbt jedoch die höchste minEngineVersion seiner aufgelösten Abhängigkeiten, sodass ein gegen eine v2- oder Range-Retention-Abhängigkeit kompiliertes v1-Modell ebenfalls eine erhält und unter ck-models/v3/ veröffentlicht wird. Die Engine lehnt ein Modell — oder eine Abhängigkeit — ab, dessen minEngineVersion über ihrer eigenen Version liegt, mit Meldung 126. (Lokale DebugL-Builds haben die Version 999.0.0 und akzeptieren alles; Engine-Builds unterhalb von Version 1.0, etwa 0.1.*-Builds des privaten Feeds, überspringen die Prüfung.)
  • Katalogpfad ck-models/v3/. Modelle mit einer minEngineVersion werden unter ck-models/v3/<letter>/<Name>/<major>/ statt unter ck-models/v2/ veröffentlicht. Engines vor CK v2 lesen nur v2, sehen also nie ein v3-Modell. CK-v2-Engines lesen beide Wurzeln (v3 zuerst). Eine Modellversion liegt in genau einer Wurzel.
<catalog>/ck-models/v2/s/System/2/ck-system-2.5.0.json # CK language 1
<catalog>/ck-models/v3/a/Acme.Assets/1/ck-acme.assets-1.0.0.json # CK language 2
Remote-Kataloge

Der lokale Dateisystem-Katalog und die GitHub-Kataloge lesen und veröffentlichen die Wurzel ck-models/v3/. Die Katalog-CI-Pipelines, die Modelle in die gemeinsamen GitHub-Kataloge veröffentlichen, verarbeiten CK-Language-2-Modelle noch nicht; das folgt in einer späteren Phase. Halten Sie CK-Language-2-Modelle bis dahin aus den gemeinsamen Katalogen heraus. Da Dependents die minEngineVersion erben, gilt dies insbesondere für Basismodelle — siehe die Betriebsregel am Anfang dieser Seite.

Engine-Versionsvertrag​

Kompiliertes ModellminEngineVersion
ckLanguage: 1, keine Range Retention, v1-Abhängigkeitenwird nicht geschrieben (Ausgabe unverändert)
ckLanguage: 2 oder Range-Retention3.5.1
CK-Language-1-Modell auf einer Abhängigkeit, die einen Wert trägtder höchste Wert seiner aufgelösten Abhängigkeiten
  • 3.5.1 ist das Minimum. Es ist das erste Bibliotheks-Release mit dem vollständigen CK-v2-Reader. Der Wert ist eine Konstante und nicht die Version der kompilierenden Engine, sodass die Compiler-Ausgabe nicht von der Build-Konfiguration abhängt. Ein früher veröffentlichtes Modell behält den Wert, mit dem es veröffentlicht wurde (veröffentlichte Modelle sind unveränderlich), zum Beispiel 3.4.0.
  • Was die laufende Engine meldet. Die Engine vergleicht Major.Minor.Patch ihres eigenen Releases. Sie liest den ersten verwendbaren Wert aus der Assembly-Dateiversion (zum Beispiel 3.5.2.0 bei einem r3.5.2-Build), der Informationsversion (ohne -slug und +commit) und der Assembly-Version; so lassen sich Patch-Releases wie 3.5.0 und 3.5.2 unterscheiden.
  • Meldung 126. Ein Modell, dessen minEngineVersion über der laufenden Engine liegt, wird mit Meldung 126 abgelehnt; sie nennt das Modell, die geforderte Version und die laufende Engine. Bei einer geforderten Version 3.5.1 lehnen die Engines 3.4.x und 3.5.0 das Modell ab; 3.5.1, 3.5.2 und 3.6.0 lesen es. Lokale DebugL-Builds haben die Version 999.0.0 und lesen alles.
  • Hauptlinien-Regel. Eine Engine mit Hauptversion kleiner als 1 (Private-Feed-Builds 0.1.YYMM.NNNN der Hauptlinie) überspringt die Prüfung, weil sie keine mit der Release-Linie vergleichbare Nummer trägt. Hauptlinien-Umgebungen sind durch die Hauptlinien-Untergrenze des Engine-Inventars und durch neu gebaute Images abgedeckt.

Ein vollständiges Beispiel​

Die Beispiele auf diesen Seiten verwenden ein Modell, Acme.Assets, das mit dem CK-v2-Compiler kompiliert:

# interfaces/interfaces.yaml
$schema: https://schemas.meshmakers.cloud/construction-kit-elements.schema.json
interfaces:
- interfaceId: Named-1
description: Anything with a human-readable name.
attributes:
- id: ${System}/Name
name: Name
- id: ${System}/Description
name: Description
isOptional: true
- interfaceId: Identified-1
description: A named thing with a serial number.
extends:
- ${this}/Named-1
attributes:
- id: ${this}/SerialNumber
name: SerialNumber
- interfaceId: Monitoring-1
description: Something that monitors identified things.
associations:
- id: ${this}/Monitors
targetCkInterfaceId: ${this}/Identified-1
multiplicity: N
- interfaceId: Calibratable-1
description: Can be calibrated.
methods:
- methodId: Calibrate-1
parameters:
- name: mode
valueType: Enum
valueCkEnumId: ${this}/CalibrationMode
- name: referenceValue
valueType: Double
isOptional: true
result:
valueType: Record
valueCkRecordId: ${this}/CalibrationResult
# types/types.yaml
$schema: https://schemas.meshmakers.cloud/construction-kit-elements.schema.json
types:
- typeId: Device
description: Base type for devices; other models may derive from it.
isAbstract: true
derivable: Any
derivedFromCkTypeId: ${System}/Entity
implements:
- ${this}/Identified-1
attributes:
- id: ${System}/Name
name: Name
- id: ${System}/Description
name: Description
isOptional: true
- id: ${this}/SerialNumber
name: SerialNumber
access: ReadOnly
- id: ${this}/Firmware
name: Firmware
isOptional: true
access: MethodOnly
- id: ${this}/ApiKeyHash
name: ApiKeyHash
isOptional: true
access: Hidden
methods:
- methodId: UpdateFirmware-1
description: Installs a firmware version.
parameters:
- name: version
valueType: String
- name: signingKey
valueType: String
sensitive: true
errors:
- code: FIRMWARE_REJECTED
description: The device refused the image.
authorization:
roles: [ AssetManagement ]
execution:
timeoutSeconds: 60
- typeId: Sensor
description: A sensor; only this model may derive from it (derivable defaults to Model).
derivedFromCkTypeId: ${this}/Device
implements:
- ${this}/Calibratable-1
- typeId: Gateway
description: Monitors devices.
derivedFromCkTypeId: ${this}/Device
implements:
- ${this}/Monitoring-1
associations:
- id: ${this}/Monitors
targetCkTypeId: ${System}/Entity
targetCkInterfaceId: ${this}/Identified-1

Die übrigen Dateien deklarieren die Attribute SerialNumber, Firmware, ApiKeyHash (alle String), CalibrationOffset (Double) und InternalNote (String, visibility: Internal), das Enum CalibrationMode, den Record CalibrationResult (Member Offset) und die Assoziationsrolle Monitors (N zu N).

Generierter Code​

Für CK-Language-2-Modelle erzeugt der Source Generator (Meshmakers.Octo.ConstructionKit.SourceGeneration) zusätzlich:

  • ein C#-Interface IRt<Name> pro CK-Interface (Named-1 → IRtNamed, Named-2 → IRtNamed2) mit Get-only-Properties für die Attribut-Member; extends wird zu C#-Interface-Vererbung, und die Rt-Klassen implementieren ihre deklarierten Interfaces explizit;
  • sealed Rt-Klassen für isFinal-Typen und für derivable: Model-Typen ohne Untertyp im eigenen Modell. Rt-Klassen von isAbstract-Typen werden vorerst nicht als C#-abstract-Klassen generiert (Repository-APIs benötigen instanziierbare Entitätsklassen); dies wird neu bewertet, wenn die System-Modelle auf CK Language 2 umgestellt werden;
  • Methoden-ID-Konstanten (DeviceUpdateFirmwareMethodId = "Acme.Assets/Device.UpdateFirmware-1"), einen {Type}{Method}Parameters-Record pro Typmethode (sensitive-Parameter werden von ToString() als *** maskiert) und einen {Type}{Method}Result-Record, wenn die Methode ein Ergebnis hat.

Die Ausgabe für CK Language 1 bleibt unverändert.

Status​

FeatureStatus
ckLanguage: 2, minEngineVersion, ck-models/v3/ (Engine-Seite)Verfügbar
Interfaces: Attribute, extends, Assoziationen, Methoden, deprecated, Compiler-ValidierungVerfügbar
visibility, derivable (zur Compile-Zeit und beim Import erneut geprüft)Verfügbar
Attribut-access im Compiler (Hidden-Regeln)Verfügbar
access-Durchsetzung in GraphQLHidden und MethodOnly werden durchgesetzt; ReadOnly noch nicht — siehe Zugriffsmodifikatoren
CK-Interfaces im GraphQL-Schema (inkl. extends), CK-Meta-API für Interfaces, Methoden und ModifikatorenVerfügbar — siehe GraphQL-Mapping
Methoden-Aufruf (GraphQL-Mutationen, Handler)Noch nicht — Methoden sind nur Definitionen
Abfrage nach Interface (runtime.byInterface, GetRtEntitiesByType nach Interface)Noch nicht
Range Retention (OctoCkRangeRetention)Preview, hinter einem Flag, standardmäßig aus
Kompatibilitätsprüfung für öffentliche Oberflächen (Phase 2)Noch nicht
ck-models/v3/ in den GitHub-KatalogenLesen und Veröffentlichen verfügbar; Katalog-CI noch nicht

Siehe auch​