diff --git a/src/Abc.ServiceModel.HL7/Abc.ServiceModel.HL7.csproj b/src/Abc.ServiceModel.HL7/Abc.ServiceModel.HL7.csproj index 53316c3..77d06ff 100644 --- a/src/Abc.ServiceModel.HL7/Abc.ServiceModel.HL7.csproj +++ b/src/Abc.ServiceModel.HL7/Abc.ServiceModel.HL7.csproj @@ -4,10 +4,17 @@ + + + Abc.ServiceModel.Protocol.HL7.SR.resources + + - + net471;net6.0;net8.0 true + 0.4.1-rc.0 + 0.4.0.2 diff --git a/src/Abc.ServiceModel.HL7/Extensions/OperationDescriptionExtensions.cs b/src/Abc.ServiceModel.HL7/Extensions/OperationDescriptionExtensions.cs index bdbcf69..917e913 100644 --- a/src/Abc.ServiceModel.HL7/Extensions/OperationDescriptionExtensions.cs +++ b/src/Abc.ServiceModel.HL7/Extensions/OperationDescriptionExtensions.cs @@ -5,6 +5,7 @@ namespace System.ServiceModel.Description #endif { using System; + using System.Linq; using System.Reflection; internal static class OperationDescriptionExtensions @@ -18,7 +19,17 @@ public static Type GetReturnType(this OperationDescription operationDescription) Type outputType = null; #if NET45_OR_GREATER || NETCOREAPP - outputType = operationDescription.TaskMethod?.ReturnType.GetGenericArguments()[0]; + // outputType = operationDescription.TaskMethod?.ReturnType.GetGenericArguments()[0]; + if (operationDescription.TaskMethod != null && + operationDescription.TaskMethod.ReturnType.GetGenericArguments().Any()) + { + outputType = operationDescription.TaskMethod?.ReturnType.GetGenericArguments()[0]; + } + else + { + outputType = operationDescription.TaskMethod?.ReturnType; + } + #endif #if NET45_OR_GREATER if (outputType == null) { diff --git a/src/Abc.ServiceModel.HL7/Extensions/XmlElementExtensions.cs b/src/Abc.ServiceModel.HL7/Extensions/XmlElementExtensions.cs new file mode 100644 index 0000000..4a621e1 --- /dev/null +++ b/src/Abc.ServiceModel.HL7/Extensions/XmlElementExtensions.cs @@ -0,0 +1,50 @@ +namespace Abc.ServiceModel.HL7.Extensions +{ + using System.Linq; + using System.Xml.Linq; + + internal static class XmlElementExtensions + { + internal static string GetElementNameWithPrefix(this XElement element) + { + //string ret = element.GetPrefixOfNamespace(element.Name.Namespace); + //if (!string.IsNullOrEmpty(ret)) + //{ + // ret += ":"; + //} + + //ret += element.Name.LocalName; + + //return ret; + + return element.Name.LocalName; + } + + internal static bool ContainsAttributesFromThisNamespace(this XElement element, string prefix) + { + if (element == null) + { + return false; + } + + if (string.IsNullOrWhiteSpace(prefix)) + { + return false; + } + + var _prefix = prefix.Trim() + ":"; + var matchingElements = element + .DescendantsAndSelf() // include the root and all its descendants + .Attributes() + .Where(attr => attr.Value != null && attr.Value.StartsWith(_prefix)) + .Select(attr => attr).ToList(); + + if (matchingElements.Any()) + { + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/src/Abc.ServiceModel.HL7/HL7/HL7ClientMessageFormatter.cs b/src/Abc.ServiceModel.HL7/HL7/HL7ClientMessageFormatter.cs index e9c94ae..b3f4e9a 100644 --- a/src/Abc.ServiceModel.HL7/HL7/HL7ClientMessageFormatter.cs +++ b/src/Abc.ServiceModel.HL7/HL7/HL7ClientMessageFormatter.cs @@ -52,7 +52,12 @@ public object DeserializeReply(Message message, object[] parameters) if (this.attribute != null && !this.attribute.AcknowledgementResponse && this.parameterType != typeof(void) && messageHl7 != null && messageHl7.ControlAct != null && messageHl7.ControlAct.Subject != null) { - body = messageHl7.ControlAct.Subject.GetBody(this.CreateInputSerializer(this.parameterType, HL7Request.RequestType.MessageRequest)); + body = messageHl7.ControlAct.Subject.GetBody( + this.CreateInputSerializer( + this.parameterType, + HL7Request.RequestType.MessageRequest, + rootName: messageHl7.ControlAct.Subject?.SubjectElementName, + rootNamespace: HL7Constants.Namespace)); } var operationContext = new HL7OperationContext(); diff --git a/src/Abc.ServiceModel.HL7/HL7/HL7DispatchMessageFormatter.cs b/src/Abc.ServiceModel.HL7/HL7/HL7DispatchMessageFormatter.cs index e0daee3..aa36818 100644 --- a/src/Abc.ServiceModel.HL7/HL7/HL7DispatchMessageFormatter.cs +++ b/src/Abc.ServiceModel.HL7/HL7/HL7DispatchMessageFormatter.cs @@ -26,7 +26,7 @@ public void DeserializeRequest(Message message, object[] parameters) operationContext.OperationContract = this.attribute; OperationContext.Current.Extensions.Add(operationContext); var messageHL7 = HL7MessageExtension.ReadHL7Message(message, this.attribute.Interaction); - + HL7Request request = messageHL7 as HL7Request; if (request == null) { @@ -44,7 +44,12 @@ public void DeserializeRequest(Message message, object[] parameters) throw new FormatException(string.Format(CultureInfo.InvariantCulture, SrProtocol.IsNotSet, "request.QueryControlAct")); } - parameters[0] = request.QueryControlAct.QueryByParameterPayload.GetBody(this.CreateInputSerializer(this.parameterType, HL7Request.RequestType.QueryParamRequest)); + parameters[0] = request.QueryControlAct.QueryByParameterPayload.GetBody( + this.CreateInputSerializer( + this.parameterType, + HL7Request.RequestType.QueryParamRequest, + rootName: request.QueryControlAct.QueryByParameterPayload.QueryByParameterPayloadElementName, + rootNamespace: HL7Constants.Namespace)); break; case HL7Request.RequestType.MessageRequest: @@ -53,8 +58,12 @@ public void DeserializeRequest(Message message, object[] parameters) { throw new FormatException(string.Format(CultureInfo.InvariantCulture, SrProtocol.IsNotSet, "request.ControlAct")); } - - var param = this.CreateInputSerializer(this.parameterType, HL7Request.RequestType.MessageRequest); + + var param = this.CreateInputSerializer( + this.parameterType, + HL7Request.RequestType.MessageRequest, + rootName: request.ControlAct.Subject?.SubjectElementName, + rootNamespace: HL7Constants.Namespace); if (request.ControlAct != null && request.ControlAct.Subject != null) { @@ -70,7 +79,12 @@ public void DeserializeRequest(Message message, object[] parameters) throw new FormatException(string.Format(CultureInfo.InvariantCulture, SrProtocol.IsNotSet, "request.QueryControlAct")); } - parameters[0] = request.QueryControlAct.QueryContinuation.GetBody(this.CreateInputSerializer(this.parameterType, HL7Request.RequestType.QueryContinuationRequest)); + parameters[0] = request.QueryControlAct.QueryContinuation.GetBody( + this.CreateInputSerializer( + this.parameterType, + HL7Request.RequestType.QueryContinuationRequest, + rootName: request.QueryControlAct.QueryContinuation?.QueryContinuationElementName, + rootNamespace: HL7Constants.Namespace)); break; default: @@ -80,7 +94,12 @@ public void DeserializeRequest(Message message, object[] parameters) throw new FormatException(string.Format(CultureInfo.InvariantCulture, SrProtocol.IsNotSet, "request.ControlAct")); } - parameters[0] = request.ControlAct.Subject.GetBody(this.CreateInputSerializer(this.parameterType, HL7Request.RequestType.MessageRequest)); + parameters[0] = request.ControlAct.Subject.GetBody( + this.CreateInputSerializer( + this.parameterType, + HL7Request.RequestType.MessageRequest, + rootName: request.ControlAct.Subject?.SubjectElementName, + rootNamespace: HL7Constants.Namespace)); break; } diff --git a/src/Abc.ServiceModel.HL7/HL7/HL7MessageFormatter.cs b/src/Abc.ServiceModel.HL7/HL7/HL7MessageFormatter.cs index 04b27e9..14a2762 100644 --- a/src/Abc.ServiceModel.HL7/HL7/HL7MessageFormatter.cs +++ b/src/Abc.ServiceModel.HL7/HL7/HL7MessageFormatter.cs @@ -66,7 +66,9 @@ private Message CreateMessageRequest(object body, string interactionId, string d return this.CreateMessageRequest(body, interactionId, deviceSender, deviceReceiver, actionCode, reasonCode, null, null, null, requestType, messageVersion); } - private Message CreateMessageRequest(object body, string interactionId, string deviceSender, string deviceReceiver, string actionCode, string reasonCode, string controlActDescription, string priorityCode, string languageCode, HL7Request.RequestType requestType, MessageVersion messageVersion) + private Message CreateMessageRequest(object body, string interactionId, + string deviceSender, string deviceReceiver, string actionCode, string reasonCode, string controlActDescription, + string priorityCode, string languageCode, HL7Request.RequestType requestType, MessageVersion messageVersion) { // if (string.IsNullOrEmpty(actionCode)) // { @@ -104,19 +106,19 @@ private Message CreateMessageRequest(object body, string interactionId, string d switch (requestType) { case HL7Request.RequestType.MessageRequest: - controlAct = new HL7MessageControlAct(overseers, dataEnterers, null, null, null, controlActDescription, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7Subject.CreateSubject(body, this.CreateOutputSerializer(body.GetType(), HL7Request.RequestType.MessageRequest))); + controlAct = new HL7MessageControlAct(overseers, dataEnterers, null, null, null, controlActDescription, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7Subject.CreateSubject(body, this.CreateOutputSerializer(body.GetType(), HL7Request.RequestType.MessageRequest, rootName: null, rootNamespace: null))); break; case HL7Request.RequestType.QueryParamRequest: - controlAct = new HL7QueryControlAcknowledgement(overseers, dataEnterers, null, null, null, controlActDescription, null, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7QueryByParameterPayload.CreateQueryByParameterPayload(body, this.CreateOutputSerializer(body.GetType(), requestType))); + controlAct = new HL7QueryControlAcknowledgement(overseers, dataEnterers, null, null, null, controlActDescription, null, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7QueryByParameterPayload.CreateQueryByParameterPayload(body, this.CreateOutputSerializer(body.GetType(), requestType, rootName: null, rootNamespace: null))); break; case HL7Request.RequestType.QueryContinuationRequest: - controlAct = new HL7QueryControlAcknowledgement(overseers, dataEnterers, null, null, null, controlActDescription, null, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7QueryContinuation.CreateQueryContinuation(body, this.CreateOutputSerializer(body.GetType(), requestType))); + controlAct = new HL7QueryControlAcknowledgement(overseers, dataEnterers, null, null, null, controlActDescription, null, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7QueryContinuation.CreateQueryContinuation(body, this.CreateOutputSerializer(body.GetType(), requestType, rootName: null, rootNamespace: null))); break; default: - controlAct = new HL7MessageControlAct(overseers, dataEnterers, null, null, null, controlActDescription, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7Subject.CreateSubject(body, this.CreateOutputSerializer(body.GetType(), HL7Request.RequestType.MessageRequest))); + controlAct = new HL7MessageControlAct(overseers, dataEnterers, null, null, null, controlActDescription, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7Subject.CreateSubject(body, this.CreateOutputSerializer(body.GetType(), HL7Request.RequestType.MessageRequest, rootName: null, rootNamespace: null))); break; } @@ -200,7 +202,7 @@ private HL7TransmissionWrapper CreateResponse(HL7OperationContext operationConte } else { - controlAct = new HL7MessageControlAct(overseers, dataEnterers, null, null, null, controlActDescription, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7Subject.CreateSubject(result, this.CreateOutputSerializer(result.GetType(), HL7Request.RequestType.MessageRequest))); + controlAct = new HL7MessageControlAct(overseers, dataEnterers, null, null, null, controlActDescription, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7Subject.CreateSubject(result, this.CreateOutputSerializer(result.GetType(), HL7Request.RequestType.MessageRequest, rootName: HL7Constants.Elements.Subject, rootNamespace: HL7Constants.Namespace))); } // return new HL7ApplicationResponse(interactionId, this.version, receiver.Id.Extension, sender.Id.Extension, controlAct, attentionLine, new HL7Acknowledgement(operationContext.MessageId, acknowledgementType != null && acknowledgementType.HasValue ? acknowledgementType.Value : HL7AcknowledgementType.ApplicationAcknowledgementAccept, operationContext.AcknowledgementDetail)); // TODO: constructor with device @@ -214,7 +216,7 @@ private HL7TransmissionWrapper CreateResponse(HL7OperationContext operationConte } else { - controlAct = new HL7QueryControlAcknowledgement(overseers, dataEnterers, null, null, null, controlActDescription, DateTime.Now, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7Subject.CreateSubject(result, this.CreateOutputSerializer(result.GetType(), HL7Request.RequestType.MessageRequest)), operationContext.QueryAcknowledgement); + controlAct = new HL7QueryControlAcknowledgement(overseers, dataEnterers, null, null, null, controlActDescription, DateTime.Now, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7Subject.CreateSubject(result, this.CreateOutputSerializer(result.GetType(), HL7Request.RequestType.MessageRequest, rootName: HL7Constants.Elements.Subject, rootNamespace: HL7Constants.Namespace)), operationContext.QueryAcknowledgement); } // return new HL7ApplicationResponse(interactionId, this.version, receiver.Id.Extension, sender.Id.Extension, controlAct, attentionLine, new HL7Acknowledgement(operationContext.MessageId, acknowledgementType != null && acknowledgementType.HasValue ? acknowledgementType.Value : HL7AcknowledgementType.ApplicationAcknowledgementAccept, operationContext.AcknowledgementDetail)); // TODO: constructor with device @@ -229,7 +231,7 @@ private HL7TransmissionWrapper CreateResponse(HL7OperationContext operationConte } else { - controlAct = new HL7QueryControlAcknowledgement(overseers, dataEnterers, null, null, null, controlActDescription, DateTime.Now, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7Subject.CreateSubject(result, this.CreateOutputSerializer(result.GetType(), HL7Request.RequestType.MessageRequest)), operationContext.QueryAcknowledgement); + controlAct = new HL7QueryControlAcknowledgement(overseers, dataEnterers, null, null, null, controlActDescription, DateTime.Now, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7Subject.CreateSubject(result, this.CreateOutputSerializer(result.GetType(), HL7Request.RequestType.MessageRequest, rootName: HL7Constants.Elements.Subject, rootNamespace: HL7Constants.Namespace)), operationContext.QueryAcknowledgement); } // return new HL7ApplicationResponse(interactionId, this.version, receiver.Id.Extension, sender.Id.Extension, controlAct, attentionLine, new HL7Acknowledgement(operationContext.MessageId, acknowledgementType != null && acknowledgementType.HasValue ? acknowledgementType.Value : HL7AcknowledgementType.ApplicationAcknowledgementAccept, operationContext.AcknowledgementDetail)); // TODO: constructor with device @@ -241,7 +243,14 @@ private HL7TransmissionWrapper CreateResponse(HL7OperationContext operationConte throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, SrProtocol.IsNotSet, "return parameter")); } - controlAct = new HL7MessageControlAct(overseers, dataEnterers, null, null, null, controlActDescription, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, HL7Subject.CreateSubject(result, this.CreateOutputSerializer(result.GetType(), HL7Request.RequestType.MessageRequest))); + controlAct = new HL7MessageControlAct( + overseers, dataEnterers, null, null, null, + controlActDescription, priorityCodeClassif, actionCode, reasonCode, languageCodeClasif, + HL7Subject.CreateSubject(result, this.CreateOutputSerializer( + result.GetType(), + HL7Request.RequestType.MessageRequest, + rootName: HL7Constants.Elements.Subject, + rootNamespace: HL7Constants.Namespace))); // return new HL7ApplicationResponse(interactionId, this.version, receiver.Id.Extension, sender.Id.Extension, controlAct, attentionLine, new HL7Acknowledgement(operationContext.MessageId, acknowledgementType != null && acknowledgementType.HasValue ? acknowledgementType.Value : HL7AcknowledgementType.ApplicationAcknowledgementAccept, operationContext.AcknowledgementDetail)); // TODO: constructor with device return new HL7ApplicationResponse(interactionId, this.version, sender.Id.Extension, receiver.Id.Extension, controlAct, attentionLine, new HL7Acknowledgement(operationContext.MessageId, acknowledgementType != null && acknowledgementType.HasValue ? acknowledgementType.Value : HL7AcknowledgementType.ApplicationAcknowledgementAccept, operationContext.AcknowledgementDetail)); // TODO: constructor with device @@ -249,69 +258,69 @@ private HL7TransmissionWrapper CreateResponse(HL7OperationContext operationConte } } - private static XmlObjectSerializer CreateSerializer(Type serializerType, Type type) + private static XmlObjectSerializer CreateSerializer(Type serializerType, Type type, string rootName, string rootNamespace) { if (serializerType != null) { - return HL7SubjectSerializerDefaults.CreateSerializer(serializerType, type); + return HL7SubjectSerializerDefaults.CreateSerializer(serializerType, type, rootName: rootName, rootNamespace: rootNamespace); } - return HL7SubjectSerializerDefaults.CreateSerializer(type); + return HL7SubjectSerializerDefaults.CreateSerializer(type, rootName: rootName, rootNamespace: rootNamespace); } - private static XmlObjectSerializer CreateSerializerQueryContinuation(Type serializerType, Type type) + private static XmlObjectSerializer CreateSerializerQueryContinuation(Type serializerType, Type type, string rootName, string rootNamespace) { if (serializerType != null) { - return HL7QueryContinuationPayloadSerializerDefaults.CreateSerializer(serializerType, type); + return HL7QueryContinuationPayloadSerializerDefaults.CreateSerializer(serializerType, type, rootName: rootName, rootNamespace: rootNamespace); } - return HL7QueryContinuationPayloadSerializerDefaults.CreateSerializer(type); + return HL7QueryContinuationPayloadSerializerDefaults.CreateSerializer(type, rootName: rootName, rootNamespace: rootNamespace); } - private static XmlObjectSerializer CreateSerializerQueryParamRequest(Type serializerType, Type type) + private static XmlObjectSerializer CreateSerializerQueryParamRequest(Type serializerType, Type type, string rootName, string rootNamespace) { if (serializerType != null) { - return HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(serializerType, type); + return HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(serializerType, type, rootName: rootName, rootNamespace: rootNamespace); } - return HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(type); + return HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(type, rootName: rootName, rootNamespace: rootNamespace); } - private XmlObjectSerializer CreateInputSerializer(Type type, HL7Request.RequestType subject) + private XmlObjectSerializer CreateInputSerializer(Type type, HL7Request.RequestType subject, string rootName, string rootNamespace) { switch (subject) { case HL7Request.RequestType.MessageRequest: - return CreateSerializer(this.inputSerializerType, type); + return CreateSerializer(this.inputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); case HL7Request.RequestType.QueryParamRequest: - return CreateSerializerQueryParamRequest(this.inputSerializerType, type); + return CreateSerializerQueryParamRequest(this.inputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); case HL7Request.RequestType.QueryContinuationRequest: - return CreateSerializerQueryContinuation(this.outputSerializerType, type); + return CreateSerializerQueryContinuation(this.outputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); default: - return CreateSerializer(this.inputSerializerType, type); + return CreateSerializer(this.inputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); } - } + } - private XmlObjectSerializer CreateOutputSerializer(Type type, HL7Request.RequestType subject) + private XmlObjectSerializer CreateOutputSerializer(Type type, HL7Request.RequestType subject, string rootName, string rootNamespace) { switch (subject) { case HL7Request.RequestType.MessageRequest: - return CreateSerializer(this.outputSerializerType, type); + return CreateSerializer(this.outputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); case HL7Request.RequestType.QueryParamRequest: - return CreateSerializerQueryParamRequest(this.outputSerializerType, type); + return CreateSerializerQueryParamRequest(this.outputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); case HL7Request.RequestType.QueryContinuationRequest: - return CreateSerializerQueryContinuation(this.outputSerializerType, type); + return CreateSerializerQueryContinuation(this.outputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); default: - return CreateSerializer(this.outputSerializerType, type); + return CreateSerializer(this.outputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); } } } diff --git a/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseClientMessageFormatter.cs b/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseClientMessageFormatter.cs index a580179..0b976f0 100644 --- a/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseClientMessageFormatter.cs +++ b/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseClientMessageFormatter.cs @@ -43,7 +43,11 @@ public object DeserializeReply(Message message, object[] parameters) if (this.attribute != null && !this.attribute.AcknowledgementResponse && this.parameterType != typeof(void)) { - body = messageHl7.ControlAct.Subject.GetBody(this.CreateInputSerializer(this.parameterType, HL7Request.RequestType.MessageRequest)); + body = messageHl7.ControlAct.Subject.GetBody(this.CreateInputSerializer( + this.parameterType, + HL7Request.RequestType.MessageRequest, + rootName: messageHl7.ControlAct.Subject.SubjectElementName, + rootNamespace: HL7Constants.Namespace)); } var operationContext = new HL7OperationContext(); diff --git a/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseDispatchMessageFormatter.cs b/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseDispatchMessageFormatter.cs index d1ca306..34b38d4 100644 --- a/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseDispatchMessageFormatter.cs +++ b/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseDispatchMessageFormatter.cs @@ -61,7 +61,12 @@ public void DeserializeRequest(Message message, object[] parameters) if (responseMess != null) { - parameters[0] = responseMess.ControlAct.Subject.GetBody(this.CreateInputSerializer(this.parameterType, HL7Request.RequestType.MessageRequest)); + parameters[0] = responseMess.ControlAct.Subject.GetBody( + this.CreateInputSerializer( + this.parameterType, + HL7Request.RequestType.MessageRequest, + rootName: responseMess.ControlAct.Subject.SubjectElementName, + rootNamespace: HL7Constants.Namespace)); } else { @@ -69,7 +74,12 @@ public void DeserializeRequest(Message message, object[] parameters) if (responseMess2 != null) { - parameters[0] = responseMess2.ControlAct.Subject.GetBody(this.CreateInputSerializer(this.parameterType, HL7Request.RequestType.MessageRequest)); + parameters[0] = responseMess2.ControlAct.Subject.GetBody( + this.CreateInputSerializer( + this.parameterType, + HL7Request.RequestType.MessageRequest, + rootName: responseMess2.ControlAct.Subject.SubjectElementName, + rootNamespace: HL7Constants.Namespace)); } else { diff --git a/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseMessageFormatter.cs b/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseMessageFormatter.cs index 634e479..42fa120 100644 --- a/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseMessageFormatter.cs +++ b/src/Abc.ServiceModel.HL7/HL7/SaveResponse/HL7SaveResponseMessageFormatter.cs @@ -58,14 +58,14 @@ internal HL7SaveResponseMessageFormatter(HL7SaveResponseOperationContractAttribu /// Type of the serializer. /// The type. /// XmlObject Serializer - private static XmlObjectSerializer CreateSerializer(Type serializerType, Type type) + private static XmlObjectSerializer CreateSerializer(Type serializerType, Type type, string rootName, string rootNamespace) { if (serializerType != null) { - return HL7SubjectSerializerDefaults.CreateSerializer(serializerType, type); + return HL7SubjectSerializerDefaults.CreateSerializer(serializerType, type, rootName: rootName, rootNamespace: rootNamespace); } - return HL7SubjectSerializerDefaults.CreateSerializer(type); + return HL7SubjectSerializerDefaults.CreateSerializer(type, rootName: rootName, rootNamespace: rootNamespace); } /// @@ -74,14 +74,14 @@ private static XmlObjectSerializer CreateSerializer(Type serializerType, Type ty /// Type of the serializer. /// The type. /// XmlObject Serializer - private static XmlObjectSerializer CreateSerializerQueryContinuation(Type serializerType, Type type) + private static XmlObjectSerializer CreateSerializerQueryContinuation(Type serializerType, Type type, string rootName, string rootNamespace) { if (serializerType != null) { - return HL7QueryContinuationPayloadSerializerDefaults.CreateSerializer(serializerType, type); + return HL7QueryContinuationPayloadSerializerDefaults.CreateSerializer(serializerType, type, rootName: rootName, rootNamespace: rootNamespace); } - return HL7QueryContinuationPayloadSerializerDefaults.CreateSerializer(type); + return HL7QueryContinuationPayloadSerializerDefaults.CreateSerializer(type, rootName: rootName, rootNamespace: rootNamespace); } /// @@ -90,49 +90,49 @@ private static XmlObjectSerializer CreateSerializerQueryContinuation(Type serial /// Type of the serializer. /// The type. /// XmlObject Serializer - private static XmlObjectSerializer CreateSerializerQueryParamRequest(Type serializerType, Type type) + private static XmlObjectSerializer CreateSerializerQueryParamRequest(Type serializerType, Type type, string rootName, string rootNamespace) { if (serializerType != null) { - return HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(serializerType, type); + return HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(serializerType, type, rootName: rootName, rootNamespace: rootNamespace); } - return HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(type); + return HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(type, rootName: rootName, rootNamespace: rootNamespace); } [System.Obsolete("obsolte", true)] - private XmlObjectSerializer CreateInputSerializer(Type type) + private XmlObjectSerializer CreateInputSerializer(Type type, string rootName, string rootNamespace) { - return CreateSerializer(this.inputSerializerType, type); + return CreateSerializer(this.inputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); } - private XmlObjectSerializer CreateInputSerializer(Type type, HL7Request.RequestType subject) + private XmlObjectSerializer CreateInputSerializer(Type type, HL7Request.RequestType subject, string rootName, string rootNamespace) { switch (subject) { case HL7Request.RequestType.MessageRequest: - return CreateSerializer(this.inputSerializerType, type); + return CreateSerializer(this.inputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); case HL7Request.RequestType.QueryParamRequest: - return CreateSerializerQueryParamRequest(this.inputSerializerType, type); + return CreateSerializerQueryParamRequest(this.inputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); case HL7Request.RequestType.QueryContinuationRequest: - return CreateSerializerQueryContinuation(this.outputSerializerType, type); + return CreateSerializerQueryContinuation(this.outputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); default: - return CreateSerializer(this.inputSerializerType, type); + return CreateSerializer(this.inputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); } } - private XmlObjectSerializer CreateOutputSerializer(Type type, HL7Request.RequestType subject) + private XmlObjectSerializer CreateOutputSerializer(Type type, HL7Request.RequestType subject, string rootName, string rootNamespace) { switch (subject) { case HL7Request.RequestType.MessageRequest: - return CreateSerializer(this.outputSerializerType, type); + return CreateSerializer(this.outputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); case HL7Request.RequestType.QueryParamRequest: - return CreateSerializerQueryParamRequest(this.outputSerializerType, type); + return CreateSerializerQueryParamRequest(this.outputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); case HL7Request.RequestType.QueryContinuationRequest: - return CreateSerializerQueryContinuation(this.outputSerializerType, type); + return CreateSerializerQueryContinuation(this.outputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); default: - return CreateSerializer(this.outputSerializerType, type); + return CreateSerializer(this.outputSerializerType, type, rootName: rootName, rootNamespace: rootNamespace); } } diff --git a/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7QueryByParameterPayload.cs b/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7QueryByParameterPayload.cs index cdeb78e..4800204 100644 --- a/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7QueryByParameterPayload.cs +++ b/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7QueryByParameterPayload.cs @@ -1,5 +1,6 @@ namespace Abc.ServiceModel.Protocol.HL7 { + using Abc.ServiceModel.HL7.Extensions; using System; using System.Diagnostics.Contracts; using System.Runtime.Serialization; @@ -44,7 +45,7 @@ public static HL7QueryByParameterPayload CreateQueryByParameterPayload(object bo { if (body == null) { throw new ArgumentNullException("body", "body != null"); } - return CreateQueryByParameterPayload(body, HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(body.GetType())); + return CreateQueryByParameterPayload(body, HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(body.GetType(), rootName: null, rootNamespace: null)); } /// @@ -77,6 +78,14 @@ public static HL7QueryByParameterPayload CreateQueryByParameterPayload(XmlReader return subject; } + /// + /// Gets the name of the QueryByParameterPayload element. + /// + /// + /// The name of the QueryByParameterPayload element. + /// + internal string QueryByParameterPayloadElementName { get; private set; } + /// /// Creates the reader. /// @@ -93,7 +102,7 @@ public virtual XmlReader CreateReader() /// An object of type T that contains the body of this message. public T GetBody() { - return (T)this.GetBody(HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(typeof(T))); + return (T)this.GetBody(HL7QueryByParameterPayloadSerializerDefaults.CreateSerializer(typeof(T), rootName: this.QueryByParameterPayloadElementName, rootNamespace: HL7Constants.Namespace)); } /// @@ -119,6 +128,7 @@ public object GetBody(XmlObjectSerializer serializerBody) /// The writer. public void WriteQueryByParameterPayload(XmlWriter writer) { + this.QueryByParameterPayloadElementName = null; if (this.data != null) { this.serializer.WriteObject(writer, this.data); @@ -136,6 +146,7 @@ public void WriteQueryByParameterPayload(XmlWriter writer) /// The writer. public virtual void WriteQueryByParameterPayload(XmlDictionaryWriter writer) { + this.QueryByParameterPayloadElementName = null; if (this.data != null) { this.serializer.WriteObject(writer, this.data); @@ -164,7 +175,28 @@ protected virtual void ReadQueryByParameterPayload(XmlReader reader) reader.ReadStartElement(HL7Constants.Elements.QueryByParameterPayload, HL7Constants.Namespace); } + var prefix = reader.Prefix; this.xmlElement = (XElement)XElement.ReadFrom(reader); + this.QueryByParameterPayloadElementName = this.xmlElement.GetElementNameWithPrefix(); + + if (this.QueryByParameterPayloadElementName == null) + { + return; + } + + //var containsAttributesFromThisNamespace = this.xmlElement.ContainsAttributesFromThisNamespace(prefix: prefix); + //this.QueryByParameterPayloadElementName += containsAttributesFromThisNamespace + // ? ":HasAttrWithPrefix:1" + // : ":HasAttrWithPrefix:0"; + + // Add missing hl7 namespace declaration if not present + if (!string.IsNullOrEmpty(prefix) && + this.xmlElement.GetNamespaceOfPrefix(prefix) == null /* && + containsAttributesFromThisNamespace */ + ) + { + this.xmlElement.Add(new XAttribute(XNamespace.Xmlns + prefix, HL7Constants.Namespace)); + } } } } \ No newline at end of file diff --git a/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7QueryContinuation.cs b/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7QueryContinuation.cs index 063d973..c1b5be6 100644 --- a/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7QueryContinuation.cs +++ b/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7QueryContinuation.cs @@ -1,5 +1,6 @@ namespace Abc.ServiceModel.Protocol.HL7 { + using Abc.ServiceModel.HL7.Extensions; using System; using System.Diagnostics.Contracts; using System.Runtime.Serialization; @@ -36,7 +37,7 @@ public static HL7QueryContinuation CreateQueryContinuation(object body) { if (body == null) { throw new ArgumentNullException("body", "body != null"); } - return CreateQueryContinuation(body, HL7SubjectSerializerDefaults.CreateSerializer(body.GetType())); + return CreateQueryContinuation(body, HL7SubjectSerializerDefaults.CreateSerializer(body.GetType(), rootName: null, rootNamespace: null)); } /// @@ -67,6 +68,14 @@ public static HL7QueryContinuation CreateQueryContinuation(XmlReader reader) return subject; } + /// + /// Gets the name of the QueryByParameterPayload element. + /// + /// + /// The name of the QueryByParameterPayload element. + /// + internal string QueryContinuationElementName { get; private set; } + /// /// Creates the reader. /// @@ -83,7 +92,7 @@ public virtual XmlReader CreateReader() /// An object of type T that contains the body of this message. public T GetBody() { - return (T)this.GetBody(HL7SubjectSerializerDefaults.CreateSerializer(typeof(T))); + return (T)this.GetBody(HL7SubjectSerializerDefaults.CreateSerializer(typeof(T), rootName: this.QueryContinuationElementName, rootNamespace: HL7Constants.Namespace)); } /// @@ -109,6 +118,7 @@ public object GetBody(XmlObjectSerializer serializer) /// The writer. public void WriteQueryContinuation(XmlWriter writer) { + this.QueryContinuationElementName = null; if (this.data != null) { this.serializer.WriteObject(writer, this.data); @@ -126,6 +136,7 @@ public void WriteQueryContinuation(XmlWriter writer) /// The writer. public virtual void WriteQueryContinuation(XmlDictionaryWriter writer) { + this.QueryContinuationElementName = null; if (this.data != null) { this.serializer.WriteObject(writer, this.data); @@ -143,7 +154,10 @@ public virtual void WriteQueryContinuation(XmlDictionaryWriter writer) /// The reader. protected virtual void ReadQueryContinuation(XmlReader reader) { - if (reader == null) { throw new ArgumentNullException("reader", "reader != null"); } + if (reader == null) + { + throw new ArgumentNullException("reader", "reader != null"); + } // Subject if (!reader.IsStartElement(HL7Constants.Elements.QueryContinuation, HL7Constants.Namespace)) @@ -151,7 +165,27 @@ protected virtual void ReadQueryContinuation(XmlReader reader) reader.ReadStartElement(HL7Constants.Elements.QueryContinuation, HL7Constants.Namespace); } + var prefix = reader.Prefix; this.xmlElement = (XElement)XElement.ReadFrom(reader); + this.QueryContinuationElementName = this.xmlElement.GetElementNameWithPrefix(); + + if (this.QueryContinuationElementName == null) + { + return; + } + + //var containsAttributesFromThisNamespace = this.xmlElement.ContainsAttributesFromThisNamespace(prefix: prefix); + //this.QueryContinuationElementName += containsAttributesFromThisNamespace + // ? ":HasAttrWithPrefix:1" + // : ":HasAttrWithPrefix:0"; + + // Add missing hl7 namespace declaration if not present + if (!string.IsNullOrEmpty(prefix) && + this.xmlElement.GetNamespaceOfPrefix(prefix) == null /* && + containsAttributesFromThisNamespace*/) + { + this.xmlElement.Add(new XAttribute(XNamespace.Xmlns + prefix, HL7Constants.Namespace)); + } } } } \ No newline at end of file diff --git a/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7Subject.cs b/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7Subject.cs index a7c5369..d4e9c13 100644 --- a/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7Subject.cs +++ b/src/Abc.ServiceModel.HL7/Protocol/HL7/Payload/HL7Subject.cs @@ -1,7 +1,10 @@ namespace Abc.ServiceModel.Protocol.HL7 { + using Abc.ServiceModel.HL7.Extensions; using System; using System.Diagnostics.Contracts; + using System.Linq; + using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Xml; using System.Xml.Linq; @@ -34,9 +37,9 @@ private HL7Subject(XmlObjectSerializer serializer, object body) /// The HL7 subject. public static HL7Subject CreateSubject(object body) { - if (body == null) { throw new ArgumentNullException("body", "body != null"); } + if (body == null) { throw new ArgumentNullException("body", "body != null"); } - return CreateSubject(body, HL7SubjectSerializerDefaults.CreateSerializer(body.GetType())); + return CreateSubject(body, HL7SubjectSerializerDefaults.CreateSerializer(body.GetType(), rootName: null, rootNamespace: null)); } /// @@ -47,8 +50,8 @@ public static HL7Subject CreateSubject(object body) /// The . public static HL7Subject CreateSubject(object body, XmlObjectSerializer serializer) { - if (body == null) { throw new ArgumentNullException("body", "body != null"); } - if (serializer == null) { throw new ArgumentNullException("serializer", "serializer != null"); } + if (body == null) { throw new ArgumentNullException("body", "body != null"); } + if (serializer == null) { throw new ArgumentNullException("serializer", "serializer != null"); } return new HL7Subject(serializer, body); } @@ -60,13 +63,22 @@ public static HL7Subject CreateSubject(object body, XmlObjectSerializer serializ /// The . public static HL7Subject CreateSubject(XmlReader reader) { - if (reader == null) { throw new ArgumentNullException("reader", "reader != null"); } + if (reader == null) { throw new ArgumentNullException("reader", "reader != null"); } var subject = new HL7Subject(); + subject.ReadSubject(reader); return subject; } + /// + /// Gets the name of the subject element. + /// + /// + /// The name of the subject element. + /// + internal string SubjectElementName { get; private set; } + /// /// Creates the reader. /// @@ -83,7 +95,7 @@ public virtual XmlReader CreateReader() /// An object of type T that contains the body of this message. public T GetBody() { - return (T)this.GetBody(HL7SubjectSerializerDefaults.CreateSerializer(typeof(T))); + return (T)this.GetBody(HL7SubjectSerializerDefaults.CreateSerializer(typeof(T), rootName: this.SubjectElementName, rootNamespace: HL7Constants.Namespace)); } /// @@ -95,7 +107,7 @@ public T GetBody() /// public object GetBody(XmlObjectSerializer serializerParam) { - if (serializerParam == null) { throw new ArgumentNullException("serializerParam", "serializerParam != null"); } + if (serializerParam == null) { throw new ArgumentNullException("serializerParam", "serializerParam != null"); } using (XmlReader reader = this.xmlElement.CreateReader()) { @@ -109,6 +121,7 @@ public object GetBody(XmlObjectSerializer serializerParam) /// The writer. public void WriteSubject(XmlWriter writer) { + this.SubjectElementName = null; if (this.data != null) { this.serializer.WriteObject(writer, this.data); @@ -126,6 +139,7 @@ public void WriteSubject(XmlWriter writer) /// The writer. public virtual void WriteSubject(XmlDictionaryWriter writer) { + this.SubjectElementName = null; if (this.data != null) { this.serializer.WriteObject(writer, this.data); @@ -143,7 +157,7 @@ public virtual void WriteSubject(XmlDictionaryWriter writer) /// The reader. protected virtual void ReadSubject(XmlReader reader) { - if (reader == null) { throw new ArgumentNullException("reader", "reader != null"); } + if (reader == null) { throw new ArgumentNullException("reader", "reader != null"); } // Subject if (!reader.IsStartElement(HL7Constants.Elements.Subject, HL7Constants.Namespace)) @@ -151,7 +165,29 @@ protected virtual void ReadSubject(XmlReader reader) reader.ReadStartElement(HL7Constants.Elements.Subject, HL7Constants.Namespace); } + var prefix = reader.Prefix; this.xmlElement = (XElement)XElement.ReadFrom(reader); + + // secibai ir nozime. sim ir jaizpildas pirms prefix pievienosanas xmlElement, jo si vertiba ietekme serializatora cache key. + this.SubjectElementName = this.xmlElement.GetElementNameWithPrefix(); + if (this.SubjectElementName == null) + { + return; + } + + //var containsAttributesFromThisNamespace = this.xmlElement.ContainsAttributesFromThisNamespace(prefix: prefix); + //this.SubjectElementName += containsAttributesFromThisNamespace + // ? ":HasAttrWithPrefix:1" + // : ":HasAttrWithPrefix:0"; + + // Add missing hl7 namespace declaration if not present + if (!string.IsNullOrEmpty(prefix) && + this.xmlElement.GetNamespaceOfPrefix(prefix) == null // && + //containsAttributesFromThisNamespace + ) + { + this.xmlElement.Add(new XAttribute(XNamespace.Xmlns + prefix, HL7Constants.Namespace)); + } } } } \ No newline at end of file diff --git a/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7QueryByParameterPayloadSerializerDefaults.cs b/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7QueryByParameterPayloadSerializerDefaults.cs index 41cf391..9e87b21 100644 --- a/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7QueryByParameterPayloadSerializerDefaults.cs +++ b/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7QueryByParameterPayloadSerializerDefaults.cs @@ -32,18 +32,22 @@ internal static class HL7QueryByParameterPayloadSerializerDefaults /// The serializer type. /// The type. /// The HL7 Subject serializer. - internal static XmlObjectSerializer CreateSerializer(Type serializerType, Type type) + internal static XmlObjectSerializer CreateSerializer(Type serializerType, Type type, string rootName, string rootNamespace) { if (serializerType == typeof(XElementObjectSerializer)) { - return new XElementObjectSerializer(HL7Constants.Elements.QueryByParameterPayload, HL7Constants.Namespace); + return HL7SerializerCache.GetXElementObjectSerializer( + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.QueryByParameterPayload : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace); } - // if (serializerType == typeof(QuerySerializer)) - // { - // return new QuerySerializer(); - // } - return (XmlObjectSerializer)Activator.CreateInstance(serializerType, type, HL7Constants.Elements.QueryByParameterPayload, HL7Constants.Namespace); + return HL7SerializerCache.GetXmlObjectSerializer( + type: type, + serializerType: serializerType, + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.QueryByParameterPayload : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace, + serializerFactory: (_type, _serializerType, _rootName, _rootNamespace) => + (XmlObjectSerializer)Activator.CreateInstance(_serializerType, _type, _rootName, _rootNamespace) ); } /// @@ -51,20 +55,28 @@ internal static XmlObjectSerializer CreateSerializer(Type serializerType, Type t /// /// The type. /// The HL7 Subject serializer. - internal static XmlObjectSerializer CreateSerializer(Type type) + internal static XmlObjectSerializer CreateSerializer(Type type, string rootName, string rootNamespace) { // Generated by XSD tools if (type.GetCustomAttributes(typeof(XmlTypeAttribute), true).Length > 0) { - return new XmlSerializerObjectSerializer(type, HL7Constants.Elements.QueryByParameterPayload, HL7Constants.Namespace); + return HL7SerializerCache.GetXmlSerializerObjectSerializer( + type: type, + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.QueryByParameterPayload : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace); } if (type == typeof(XElement)) { - return new XElementObjectSerializer(HL7Constants.Elements.QueryByParameterPayload, HL7Constants.Namespace); + return HL7SerializerCache.GetXElementObjectSerializer( + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.QueryByParameterPayload : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace); } - return new DataContractSerializer(type, HL7Constants.Elements.QueryByParameterPayload, HL7Constants.Namespace); + return HL7SerializerCache.GetDataContractSerializer( + type: type, + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.QueryByParameterPayload : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace); } } } \ No newline at end of file diff --git a/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7QueryContinuationPayloadSerializerDefaults.cs b/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7QueryContinuationPayloadSerializerDefaults.cs index 13c73d6..a3a8067 100644 --- a/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7QueryContinuationPayloadSerializerDefaults.cs +++ b/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7QueryContinuationPayloadSerializerDefaults.cs @@ -32,18 +32,22 @@ internal static class HL7QueryContinuationPayloadSerializerDefaults /// The serializer type. /// The type. /// The HL7 Subject serializer. - internal static XmlObjectSerializer CreateSerializer(Type serializerType, Type type) + internal static XmlObjectSerializer CreateSerializer(Type serializerType, Type type, string rootName, string rootNamespace) { if (serializerType == typeof(XElementObjectSerializer)) { - return new XElementObjectSerializer(HL7Constants.Elements.QueryContinuation, HL7Constants.Namespace); + return HL7SerializerCache.GetXElementObjectSerializer( + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.QueryContinuation : rootName, + rootNamespace: string.IsNullOrWhiteSpace( rootNamespace ) ? HL7Constants.Namespace : rootNamespace ); } - // if (serializerType == typeof(QuerySerializer)) - // { - // return new QuerySerializer(); - // } - return (XmlObjectSerializer)Activator.CreateInstance(serializerType, type, HL7Constants.Elements.QueryContinuation, HL7Constants.Namespace); + return HL7SerializerCache.GetXmlObjectSerializer( + type: type, + serializerType: serializerType, + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.QueryContinuation : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace, + serializerFactory: (_type, _serializerType, _rootName, _rootNamespace) => + (XmlObjectSerializer)Activator.CreateInstance(_serializerType, _type, _rootName, _rootNamespace)); } /// @@ -51,20 +55,28 @@ internal static XmlObjectSerializer CreateSerializer(Type serializerType, Type t /// /// The type. /// The HL7 Subject serializer. - internal static XmlObjectSerializer CreateSerializer(Type type) + internal static XmlObjectSerializer CreateSerializer(Type type, string rootName, string rootNamespace) { // Generated by XSD tools if (type.GetCustomAttributes(typeof(XmlTypeAttribute), true).Length > 0) { - return new XmlSerializerObjectSerializer(type, HL7Constants.Elements.QueryContinuation, HL7Constants.Namespace); + return HL7SerializerCache.GetXmlSerializerObjectSerializer( + type: type, + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.QueryContinuation : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace); } if (type == typeof(XElement)) { - return new XElementObjectSerializer(HL7Constants.Elements.QueryContinuation, HL7Constants.Namespace); + return HL7SerializerCache.GetXElementObjectSerializer( + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.QueryContinuation : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace); } - return new DataContractSerializer(type, HL7Constants.Elements.QueryContinuation, HL7Constants.Namespace); + return HL7SerializerCache.GetDataContractSerializer( + type: type, + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.QueryContinuation : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace); } } } \ No newline at end of file diff --git a/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7SerializerCache.cs b/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7SerializerCache.cs new file mode 100644 index 0000000..08b6871 --- /dev/null +++ b/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7SerializerCache.cs @@ -0,0 +1,101 @@ +namespace Abc.ServiceModel.Protocol.HL7 +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Reflection; + using System.Runtime.Serialization; + using System.Security; + using System.Text; + using System.Threading; + using System.Threading.Tasks; + using System.Xml.Serialization; + + internal static class HL7SerializerCache + { + private static ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); + private static Dictionary _xmlSerializers = new Dictionary(StringComparer.OrdinalIgnoreCase); + + internal static DataContractSerializer GetDataContractSerializer(Type type, string rootName, string rootNamespace) => + GetXmlObjectSerializer( + type: type, + serializerType: null, + rootName: rootName, + rootNamespace: rootNamespace, + serializerFactory: (_type, _serializerType, _rootName, _rootNamespace) => + new DataContractSerializer( + type: _type, + rootName: _rootName, + rootNamespace: _rootNamespace)); + + internal static XElementObjectSerializer GetXElementObjectSerializer(string rootName, string rootNamespace) => + GetXmlObjectSerializer( + type: typeof(XElementObjectSerializer), + serializerType: null, + rootName: rootName, + rootNamespace: rootNamespace, + serializerFactory: (_type, _serializerType, _rootName, _rootNamespace) => + new XElementObjectSerializer( + rootName: _rootName, + rootNamespace: _rootNamespace)); + + + internal static XmlSerializerObjectSerializer GetXmlSerializerObjectSerializer(Type type, string rootName, string rootNamespace) => + GetXmlObjectSerializer( + type: type, + serializerType: null, + rootName: rootName, + rootNamespace: rootNamespace, + serializerFactory: (_type, _serializerType, _rootName, _rootNamespace) => + new XmlSerializerObjectSerializer( + type: _type, + rootName: _rootName, + rootNamespace: _rootNamespace)); + + internal static T GetXmlObjectSerializer(Type type, Type serializerType, string rootName, string rootNamespace, Func serializerFactory) + where T : XmlObjectSerializer + { + XmlObjectSerializer xmlObjectSerializer = null; + + string key = typeof(T).Name + type?.FullName + ":" + rootNamespace + ":" + rootName; + _lock.EnterUpgradeableReadLock(); + try + { + if (!_xmlSerializers.TryGetValue(key, out xmlObjectSerializer)) + { + _lock.EnterWriteLock(); + try + { + if (!_xmlSerializers.TryGetValue(key, out xmlObjectSerializer)) + { + if (xmlObjectSerializer == null) + { + string normalizedRootName = rootName; + if (normalizedRootName != null) + { + normalizedRootName = normalizedRootName.Replace(":HasAttrWithPrefix:1", string.Empty); + normalizedRootName = normalizedRootName.Replace(":HasAttrWithPrefix:0", string.Empty); + } + + xmlObjectSerializer = serializerFactory(type, serializerType, normalizedRootName, rootNamespace); + } + + _xmlSerializers.Add(key, xmlObjectSerializer); + } + } + finally + { + _lock.ExitWriteLock(); + } + } + } + finally + { + _lock.ExitUpgradeableReadLock(); + } + + return xmlObjectSerializer as T; + } + } +} \ No newline at end of file diff --git a/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7SubjectSerializerDefaults.cs b/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7SubjectSerializerDefaults.cs index 6ac2594..92b6b86 100644 --- a/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7SubjectSerializerDefaults.cs +++ b/src/Abc.ServiceModel.HL7/Protocol/HL7/SerializerDefaults/HL7SubjectSerializerDefaults.cs @@ -27,18 +27,22 @@ internal static class HL7SubjectSerializerDefaults /// The serializer type. /// The type. /// The HL7 Subject serializer. - internal static XmlObjectSerializer CreateSerializer(Type serializerType, Type type) + internal static XmlObjectSerializer CreateSerializer(Type serializerType, Type type, string rootName, string rootNamespace) { if (serializerType == typeof(XElementObjectSerializer)) { - return new XElementObjectSerializer(HL7Constants.Elements.Subject, HL7Constants.Namespace); + return HL7SerializerCache.GetXElementObjectSerializer( + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.Subject : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace); } - - // if (serializerType == typeof(QuerySerializer)) - // { - // return new QuerySerializer(); - // } - return (XmlObjectSerializer)Activator.CreateInstance(serializerType, type, HL7Constants.Elements.Subject, HL7Constants.Namespace); + + return HL7SerializerCache.GetXmlObjectSerializer( + type: type, + serializerType: serializerType, + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.Subject : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace, + serializerFactory: (_type, _serializerType, _rootName, _rootNamespace) => + (XmlObjectSerializer)Activator.CreateInstance(_serializerType, _type, _rootName, _rootNamespace)); } /// @@ -46,22 +50,30 @@ internal static XmlObjectSerializer CreateSerializer(Type serializerType, Type t /// /// The type. /// The HL7 Subject serializer. - internal static XmlObjectSerializer CreateSerializer(Type type) + internal static XmlObjectSerializer CreateSerializer(Type type, string rootName, string rootNamespace) { - if (type == null) { throw new ArgumentNullException("type", "type != null"); } + if (type == null) { throw new ArgumentNullException("type", "type != null"); } // Generated by XSD tools if (type.GetCustomAttributes(typeof(XmlTypeAttribute), true).Length > 0) { - return new XmlSerializerObjectSerializer(type, HL7Constants.Elements.Subject, HL7Constants.Namespace); + return HL7SerializerCache.GetXmlSerializerObjectSerializer( + type: type, + rootName: string.IsNullOrWhiteSpace( rootName ) ? HL7Constants.Elements.Subject : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace ); } if (type == typeof(XElement)) { - return new XElementObjectSerializer(HL7Constants.Elements.Subject, HL7Constants.Namespace); + return HL7SerializerCache.GetXElementObjectSerializer( + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.Subject : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace); } - return new DataContractSerializer(type, HL7Constants.Elements.Subject, HL7Constants.Namespace); + return HL7SerializerCache.GetDataContractSerializer( + type: type, + rootName: string.IsNullOrWhiteSpace(rootName) ? HL7Constants.Elements.Subject : rootName, + rootNamespace: string.IsNullOrWhiteSpace(rootNamespace) ? HL7Constants.Namespace : rootNamespace); } } } \ No newline at end of file