IMessage
IMessage describes message with arguments, code, id, time and error fields.
/// <summary>Message entry with arguments.</summary>
/// <remarks>
/// Message <see cref="IDictionary"/> implementation provides parameter name to argument mapping.
/// Message <see cref="object.ToString"/> prints <see cref="Arguments"/> in <see cref="IMessageDescription.Template"/> using 'null' culture.
/// </remarks>
public interface IMessage : IDictionary, IDictionary<string, object?>, IUserDataContainer, IFormattable, ISpanFormattable
{
/// <summary>Message identification, such as <see cref="int"/> or <see cref="Guid"/></summary>
object? Id { get; set; }
/// <summary>Message description.</summary>
IMessageDescription MessageDescription { get; set; }
/// <summary>Arguments.</summary>
object?[] Arguments { get; set; }
/// <summary>Event occurance time.</summary>
DateTime? Time { get; set; }
/// <summary>Message severity level for logging.</summary>
MessageLevel? Severity { get; set; }
/// <summary>Captured error</summary>
Exception? Error { get; set; }
/// <summary>Inner messages</summary>
IMessage[]? InnerMessages { get; set; }
}
Message is the default implementation.
IMessage message = new Message(
messageDescription: CoreMessages.Instance.GoodValid,
arguments: obj
);
IMessage can be constructed with IMessageDescription.New(arguments) extension method.
IMessage goodStatus = CoreMessages.Instance.GoodValid.New(obj);
IMessage errorStatus = CoreMessages.Instance.BadNotValid.New(obj, "Unexpected");
IMessage errorStatusNullArg = CoreMessages.Instance.BadNullArgument.New(obj, "Name");
ValueMessage is value-typed implementation. It can be used as zero heap message type for example in rapid eventing.
ValueMessage message = new ValueMessage(
messageDescription: CoreMessages.Instance.GoodValid,
arguments: new object()
);
IMessageDescription.NameOf(expression) constructs message from expression text. See mscorlib.dll scraped Argument, ArgumentNull and ArgumentOutOfRange validation messages.
object argument = null!;
IMessage msg = SystemMessages.ArgumentNull.WithParamName.NameOf(argument);
WriteLine(msg); // Parameter 'argument' cannot be null.
.SetId(object) assigns message event id. IIdGenerator generates unique identities.
object obj = new object();
IMessage msg = CoreMessages.Instance.BadNotValid.New(obj, "Unknown").SetId(IdGenerators.Guid.Next);
WriteLine(msg.Id); // "679b2f1a-3341-4cc6-81d6-5c55bbdde164"
.SetTime(time) assigns event occurance time.
object obj = new object();
IMessage msg = CoreMessages.Instance.BadNotValid.New(obj, "Unknown").SetTime(DateTime.Now);
WriteLine(msg.Time); //
.SetNow() assigns event occurance time as now.
object obj = new object();
IMessage msg = CoreMessages.Instance.BadNotValid.New(obj, "Unknown").SetNow();
WriteLine(msg.Time); //
.UserData stores user data. Dictionary is lazy constructed and safe for concurrent use. See IUserDataContainer.
// Create message
IMessage msg = CoreMessages.Instance.BadReadOnly.New();
// Set data
msg.UserData["Hello"] = "World";
// Read data
WriteLine(msg.UserData["Hello"]); // "World"
.SetUserData(key, value) assigns value to user data.
// Create message
IMessage msg = CoreMessages.Instance
.BadReadOnly
.New()
.SetUserData("Hello", "World");
// Read data
WriteLine(msg.UserData["Hello"]); // "World"
IDictionary implementation reflects parameter to argument mapping.
// Create message without argument
IMessage msg = CoreMessages.Instance.BadUnexpected.New();
// Cast to dictionary
IDictionary<string, object?> args = msg;
// Assign argument to parameter
args["object"] = "MyObject";
// Print "'MyObject': Could not change object in read-only state."
WriteLine(msg);
.InnerMessage holds an inner message.
// Create inner message
IMessage msg1 = CoreMessages.Instance.BadReadOnly.New();
// Create outer message
IMessage msg2 = CoreMessages.Instance.BadUnexpected.New().SetInnerMessage(msg1);
Message.SetInterpolated(string) assigns message description and arguments from an interpolated string.
// Create arguments
string user = "User";
DateTime time = DateTime.Now;
long errorCode = 0x80000000;
// Create message
IMessage message = new Message().SetInterpolated($"Hello {user}, time is {time}, error is [0x{errorCode:X8}].");
// Print text
WriteLine(message); // "Hello User, time is 10.1.2022 23.22.55, error is [0x80000000]."
// Print template text
WriteLine(message.MessageDescription.Template); // "Hello {0}, time is {1}, error is [0x{2:X8}]."
// Print argument
WriteLine(message.Arguments[0]); // "User"
// Reconstruct template
string assembly = TemplateFormat.Percent.Assemble[message.MessageDescription.Template.Breakdown];
// Print assembly
WriteLine(assembly); // "Hello %1, time is %2, error is [0x%3]."
Message is assignable to interpolated string parameters due to FormattableString implementation.
// Create template
ITemplateText text = TemplateFormat.Percent.Text["Hello %1, time is %2."];
// Create message description
IMessageDescription messageDescription = new MessageDescription().SetTemplate(text);
// Create message
Message message = messageDescription.New("User", DateTime.Now);
// Cast to FormattableString
FormattableString formattableString = message;
// Use like string interpolation
WriteLine(FormattableString.Invariant(formattableString)); // "Hello User, time is 01/10/2022 21:56:49."
Full Example
Full example
using System;
using System.Collections;
using System.Collections.Generic;
using Avalanche.Utilities;
using Avalanche.Message;
using static System.Console;
using Avalanche.StatusCode;
using System.Globalization;
using Avalanche.Template;
class message_index
{
public static void Run()
{
{
object obj = new object();
// <01>
IMessage message = new Message(
messageDescription: CoreMessages.Instance.GoodValid,
arguments: obj
);
// </01>
// <02>
IMessage goodStatus = CoreMessages.Instance.GoodValid.New(obj);
IMessage errorStatus = CoreMessages.Instance.BadNotValid.New(obj, "Unexpected");
IMessage errorStatusNullArg = CoreMessages.Instance.BadNullArgument.New(obj, "Name");
// </02>
}
{
// <03>
ValueMessage message = new ValueMessage(
messageDescription: CoreMessages.Instance.GoodValid,
arguments: new object()
);
// </03>
}
{
// <04>
object argument = null!;
IMessage msg = SystemMessages.ArgumentNull.WithParamName.NameOf(argument);
WriteLine(msg); // Parameter 'argument' cannot be null.
// </04>
}
{
// <05>
object obj = new object();
IMessage msg = CoreMessages.Instance.BadNotValid.New(obj, "Unknown").SetId(IdGenerators.Guid.Next);
WriteLine(msg.Id); // "679b2f1a-3341-4cc6-81d6-5c55bbdde164"
// </05>
}
{
// <06>
object obj = new object();
IMessage msg = CoreMessages.Instance.BadNotValid.New(obj, "Unknown").SetTime(DateTime.Now);
WriteLine(msg.Time); //
// </06>
}
{
// <07>
object obj = new object();
IMessage msg = CoreMessages.Instance.BadNotValid.New(obj, "Unknown").SetNow();
WriteLine(msg.Time); //
// </07>
}
{
// <08>
// Create message
IMessage msg = CoreMessages.Instance.BadReadOnly.New();
// Set data
msg.UserData["Hello"] = "World";
// Read data
WriteLine(msg.UserData["Hello"]); // "World"
// </08>
}
{
// <09>
// Create message
IMessage msg = CoreMessages.Instance
.BadReadOnly
.New()
.SetUserData("Hello", "World");
// Read data
WriteLine(msg.UserData["Hello"]); // "World"
// </09>
}
{
// <11>
// Create message without argument
IMessage msg = CoreMessages.Instance.BadUnexpected.New();
// Cast to dictionary
IDictionary<string, object?> args = msg;
// Assign argument to parameter
args["object"] = "MyObject";
// Print "'MyObject': Could not change object in read-only state."
WriteLine(msg);
// </11>
}
{
// <13>
// Create inner message
IMessage msg1 = CoreMessages.Instance.BadReadOnly.New();
// Create outer message
IMessage msg2 = CoreMessages.Instance.BadUnexpected.New().SetInnerMessage(msg1);
// </13>
}
{
// <40>
// Create arguments
string user = "User";
DateTime time = DateTime.Now;
long errorCode = 0x80000000;
// Create message
IMessage message = new Message().SetInterpolated($"Hello {user}, time is {time}, error is [0x{errorCode:X8}].");
// Print text
WriteLine(message); // "Hello User, time is 10.1.2022 23.22.55, error is [0x80000000]."
// Print template text
WriteLine(message.MessageDescription.Template); // "Hello {0}, time is {1}, error is [0x{2:X8}]."
// Print argument
WriteLine(message.Arguments[0]); // "User"
// Reconstruct template
string assembly = TemplateFormat.Percent.Assemble[message.MessageDescription.Template.Breakdown];
// Print assembly
WriteLine(assembly); // "Hello %1, time is %2, error is [0x%3]."
// </40>
}
{
// <41>
// Create template
ITemplateText text = TemplateFormat.Percent.Text["Hello %1, time is %2."];
// Create message description
IMessageDescription messageDescription = new MessageDescription().SetTemplate(text);
// Create message
Message message = messageDescription.New("User", DateTime.Now);
// Cast to FormattableString
FormattableString formattableString = message;
// Use like string interpolation
WriteLine(FormattableString.Invariant(formattableString)); // "Hello User, time is 01/10/2022 21:56:49."
// </41>
}
}
}