/// <summary> /// Get message types for specified locale. /// </summary> /// <param name="locale">Locale.</param> /// <returns>Message types for specified locale.</returns> protected virtual MessageTypeList GetMessageTypes(ILocale locale) { MessageTypeList messageTypes = null; if (MessageTypes.ContainsKey(locale.ISOCode)) { messageTypes = (MessageTypeList)(MessageTypes[locale.ISOCode]); } return(messageTypes); }
// Implement collection symantics so that we can work as a collection // of message types. /// <summary> /// Add a message type to this decoder /// </summary> /// <param name="type">Type of a message class</param> public void Add(Type type) { string attribNameValue = MessageBase.LookupMessageName(type); Contracts.IsNotNullOrWhitespace(attribNameValue, $"Invalid command Name attribute is set for the command or response structure. {type}"); if (!MessageTypes.ContainsKey(attribNameValue)) { MessageTypes.Add(attribNameValue, type); } }
/// <summary> /// Unserialise to an object based on the Name of header /// registered with this MessageDecoder collection. /// </summary> /// <remarks> /// JSON must contain an Name field in the Headers. /// JSON must match type registered for that Name. /// </remarks> /// <param name="JSON">JSON for object</param> /// <param name="result">Resulting Message object</param> /// <returns>true if de-serialisation worked</returns> public bool TryUnserialise(string JSON, out object result) { result = default; string messageName = null; // Sniff headers first and know message type if (searchType == typeof(CommandAttribute) || searchType == typeof(CompletionAttribute)) { if (!TryUnserialise(JSON, typeof(MessageDeserializerHelper <MessagePayloadBase>), out object objMessage)) { return(false); } if (objMessage is null || objMessage is not MessageDeserializerHelper <MessagePayloadBase> ) { Contracts.Fail($"Failed to unserialize JSON message in the {nameof(TryUnserialise)} nethod. SearchType:{searchType} Contents: {JSON}"); } MessageDeserializerHelper <MessagePayloadBase> baseMessage = objMessage as MessageDeserializerHelper <MessagePayloadBase>; messageName = baseMessage.Headers.Name; } else { Contracts.Fail($"MessageDecoder requires to register for command or response to populate message classes."); } Contracts.IsNotNullOrWhitespace(messageName, $"Failed to unserialize JOSN message. {JSON}"); if (!MessageTypes.ContainsKey(messageName)) { return(false); } // Now we know the type of message and deserialize it Type thisMessageType = MessageTypes[messageName]; thisMessageType.BaseType.IsNotNull($"MessageType does not have base type. {nameof(thisMessageType)}"); Contracts.Assert(thisMessageType.BaseType.IsGenericType, $"MessageType base type is not generic. {nameof(thisMessageType)}"); Type payloadType = thisMessageType.BaseType.GetGenericArguments()[0]; //Get payload type Contracts.Assert(payloadType.IsSubclassOf(typeof(MessagePayloadBase)) || payloadType == typeof(MessagePayloadBase), $"Payload type was not {nameof(MessagePayloadBase)}. {nameof(payloadType)}"); //Deserialise as MessageDeserializerHelper<payloadType> to avoid requiring MessageHeader in the "thisMessageType" constructor. if (TryUnserialise(JSON, typeof(MessageDeserializerHelper <>).MakeGenericType(new Type[] { payloadType }), out result)) { result = ((IDeserializerHelper)result).CreateMessage(thisMessageType); //Create the message object using its constructor. return(result != null && result.GetType() == thisMessageType); } return(false); }
/// <summary> /// Get message types for specified locale. /// </summary> /// <param name="locale">Locale.</param> /// <returns>Message types for specified locale.</returns> protected override MessageTypeList GetMessageTypes(ILocale locale) { MessageTypeList messageTypes = null; lock (MessageTypes) { if (MessageTypes.ContainsKey(locale.ISOCode)) { messageTypes = (MessageTypeList)(MessageTypes[locale.ISOCode]); } } if (messageTypes.IsNotNull()) { return(messageTypes.CloneMessageTypeList()); } else { return(messageTypes); } }