IDataType
IDataType is root interface for datatype descriptions. It carries no fields, but has some expected features.
/// <summary>Datatype root interface</summary>
public interface IDataType : IGraphComparable, IGraphEqualityComparable, ICloneable, IRecord, INominable, IDefaultValued<object?>
{
/// <summary>The interface type.</summary>
[IgnoreDataMember] Type IntfType { get; set; }
/// <summary>Component types</summary>
[IgnoreDataMember] IDataType[] Components { get; }
/// <summary>The container of this type is capable of holding unassigned state, also known as 'nullable', 'optional', and complement of 'required'.</summary>
bool Unassignable { get; set; }
/// <summary>Is instance of the type referable by identity.</summary>
bool Referable { get; set; }
/// <summary>Annotations. See <see cref="Annotation"/> for keys of wellknown annotations.</summary>
IDictionary<string, string> Annotations { get; set; }
/// <summary>Keys for wellknown keys for <see cref="Annotations"/>.</summary>
public static class Annotation
{
/// <summary>Human readable description text about the type.</summary>
public const string Description = nameof(Description);
/// <summary>Human readable name of the type.</summary>
public const string DisplayName = nameof(DisplayName);
}
}
/// <summary>Contains Name property.</summary>
public interface INominable
{
/// <summary>Object name</summary>
IIdentity? Name { get; set; }
}
/// <summary>Contains default value property.</summary>
public interface IDefaultValued<T>
{
/// <summary>Possible default value of <typeparamref name="T"/>.</summary>
T DefaultValue { get; set; }
}
Avalanche.DataType introduces following basic datatypes:
IDataType ├── IRecordType ├── IFieldType ├── IOneOfType ├── IListType │ └── IStringType ├── IValueType │ └── INumberType │ ├── IIntegerType │ │ └── IEnumerationType │ └── IRealType └── IAnyType
Annotations
Well-known annotations.
Field | Key | Type | Description |
---|---|---|---|
IDataType.Annotation.Description | Description | string | Human readable datatype description. |
IDataType.Annotation.DisplayName | DisplayName | string | Human readable type name. |
Implementation
IDataType base interface can be extended for third party types.
public interface IMessageType : IDataType
{
IDataType Request { get; set; }
IDataType Response { get; set; }
}
DataType is the class base for third party types.
public class MessageType : DataType, IMessageType
{
/// <summary>Interface Type</summary>
[IgnoreDataMember] public override Type IntfType { get => typeof(IMessageType); set => CoreMessages.Instance.BadReadOnly.Throw(); }
[IgnoreDataMember] protected IDataType request = null!;
[IgnoreDataMember] protected IDataType response = null!;
public IDataType Request { get => request; set => this.AssertWritable().request = value; }
public IDataType Response { get => response; set => this.AssertWritable().response = value; }
/// <summary>Check validation.</summary>
protected override void InternalValidate(ref StructList1<IMessage> errorCodes)
{
// Call base implementation
base.InternalValidate(ref errorCodes);
// Test properties
if (Request == null) errorCodes.Add(DataTypeMessages.Instance.BadFieldNotFound.New(nameof(Request)));
if (Response == null) errorCodes.Add(DataTypeMessages.Instance.BadFieldNotFound.New(nameof(Response)));
}
}
Values are assignable with initializer.
// Create message description
IMessageType messageType = new MessageType
{
Name = Identities.CreateName("LookupMessage"),
Description = "Table lookup message",
Annotations = new LockableDictionary<string, string>(),
DefaultValue = null,
Unassignable = false,
Referable = true,
Request = DataTypes.String.Instance,
Response = DataTypes.String.Instance
}
.SetReadOnly();
And values are assignable with extension method setters.
// Create message description
IMessageType messageType = new MessageType
{
Request = DataTypes.String.Instance,
Response = DataTypes.String.Instance
}
.SetName(Identities.CreateName("LookupMessage"))
.SetDescription("Table lookup message")
.SetAnnotations(new LockableDictionary<string, string>())
.SetDefaultValue<MessageType, object?>(null)
.SetUnassignable(false)
.SetReferable(true)
.SetReadOnly();
Base class implements ICloneable and IGraphCloneable.
MessageType clone = (MessageType)messageType.Clone();
Extension method for IValidable asserts data type is valid.
MessageType messageType = new MessageType();
IMessage statusCode = messageType.ValidateSingle();
WriteLine(statusCode); // "Request: Not found."
Full Example
Full example
using System;
using System.Runtime.Serialization;
using Avalanche.Accessor;
using Avalanche.DataType;
using Avalanche.Identity;
using Avalanche.Utilities;
using Avalanche.Message;
using static System.Console;
public class datatype
{
public static void Run()
{
{
// <01>
// Create message description
IMessageType messageType = new MessageType
{
Name = Identities.CreateName("LookupMessage"),
Description = "Table lookup message",
Annotations = new LockableDictionary<string, string>(),
DefaultValue = null,
Unassignable = false,
Referable = true,
Request = DataTypes.String.Instance,
Response = DataTypes.String.Instance
}
.SetReadOnly();
// </01>
}
{
// <02>
// Create message description
IMessageType messageType = new MessageType
{
Request = DataTypes.String.Instance,
Response = DataTypes.String.Instance
}
.SetName(Identities.CreateName("LookupMessage"))
.SetDescription("Table lookup message")
.SetAnnotations(new LockableDictionary<string, string>())
.SetDefaultValue<MessageType, object?>(null)
.SetUnassignable(false)
.SetReferable(true)
.SetReadOnly();
// </02>
// <03>
MessageType clone = (MessageType)messageType.Clone();
// </03>
}
{
// <04>
MessageType messageType = new MessageType();
IMessage statusCode = messageType.ValidateSingle();
WriteLine(statusCode); // "Request: Not found."
// </04>
}
}
// <200>
public interface IMessageType : IDataType
{
IDataType Request { get; set; }
IDataType Response { get; set; }
}
// </200>
// <201>
public class MessageType : DataType, IMessageType
{
/// <summary>Interface Type</summary>
[IgnoreDataMember] public override Type IntfType { get => typeof(IMessageType); set => CoreMessages.Instance.BadReadOnly.Throw(); }
[IgnoreDataMember] protected IDataType request = null!;
[IgnoreDataMember] protected IDataType response = null!;
public IDataType Request { get => request; set => this.AssertWritable().request = value; }
public IDataType Response { get => response; set => this.AssertWritable().response = value; }
/// <summary>Check validation.</summary>
protected override void InternalValidate(ref StructList1<IMessage> errorCodes)
{
// Call base implementation
base.InternalValidate(ref errorCodes);
// Test properties
if (Request == null) errorCodes.Add(DataTypeMessages.Instance.BadFieldNotFound.New(nameof(Request)));
if (Response == null) errorCodes.Add(DataTypeMessages.Instance.BadFieldNotFound.New(nameof(Response)));
}
}
// </201>
}