Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Azure

Service-Orientation with .NET : Service Contracts and Interoperability - Data Model Transformation

5/7/2011 10:33:30 AM
- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
One goal of the Standardized Service Contract  principle is to avoid having to transform data at runtime. This means that the more successfully and broadly we are able to apply this principle, the less need we will have for patterns like Data Model Transformation . However, even when seeking service contract standardization, there are situations where this pattern is necessary.

For example:

  • When an IT enterprise has multiple domain service inventories, each collection of services can be subject to different design standards. In this case, when required to enable cross-inventory communication (or when creating a service composition comprised of services from multiple service inventories), any disparity in message data models will need to be overcome by applying Data Model Transformation.

  • When data needs to be shared between different organizations (or organizational entities), Data Model Transformation will generally be required unless Canonical Schema  has been successfully applied via the use of custom or industry-standard message schemas.

  • When services encapsulate legacy systems and resources, they will inevitably need to transform data between legacy data models and the standardized data model defined in the service contracts. In this case, Data Model Transformation is carried out within the service architecture.

  • When services within a service inventory are not all successfully standardized (meaning the Standardized Service Contract  principle was not applied to its full extent), Data Model Transformation  will be required to enable the necessary interoperability.

Data Model Transformation is generally carried out by creating mapping logic between disparate schemas or data types (Figure 1). This type of logic can often become complex and is sometimes even impossible to develop when the disparity between data models is too large.

Figure 1. Service A sends a message to Service B. The message sent by Service A contains address data that was defined by a schema that is different than the schema Service B uses in its service contract for this same information. Therefore, transformation logic is processed by a service agent in order to transform the message at runtime into data that complies with Service B’s schema.


For example, you may encounter mandatory fields in one model that don’t exist in the other. In such a case, transforming in one direction may work, but transforming in the opposite direction may not. The following example demonstrates by showing how we may not be able to determine which value(s) belong in the middleNames element:

Example 1. Transforming from Data Model #1 to Data Model #2 works, but the opposite transformation is more difficult.

Data Model #1

<person1>
<foreNames>Max</foreNames>
<middleNames>Carl</middleNames>
<surNames>von Sydow</surNames>
</person1>

Data Model #2

<person2>
<name>Max Carl von Sydow</name>
</person2>

Besides the potential complexity of mapping logic, there are other well-known impacts of applying this pattern. The additional logic will introduce development and governance effort, and can further affect the performance of services and service compositions (sometimes significantly so, especially with more complex mapping logic).

The following sections briefly show three ways to apply Data Model Transformation  using .NET technologies.

Object-to-Object

A message sent by a service consumer to a service can be serialized from XML into an object, translated into another object, and then serialized into XML again. This may be a suitable approach when you must use all or most of the data in the message, either for passing the information onto another service or for some other purpose.

The first step in this process is to understand the mapping requirements. Let’s take, for example, a scenario where we need to transform data defined by a person type into a customer type (Figure 2). The logic behind this transformation could be as follows:

  • map the person.id field to the customer.id field

  • map the person.foreName field to the customer.firstName field

  • map the person.surName field to the customer.lastName field

  • map the person.address.phone field to the customer.phone field

  • map the person.gender field to the customer.gender field

Figure 2. Mapping fields from the person type to the customer type.

After generating proxy clients for the different services with the “Add service reference” feature of Visual Studio, we also have .NET code that represents a person and a customer. The translation could then be programmed using a static extension method as shown here:

Example 2.
public static Customer TransformPersonToCustomer
(this Person person)
{
Customer customer = new Customer();
customer.id = person.Id;
customer.firstName = person.ForeName;
customer.lastName = person.SurName;
customer.phone = person.Address.PhoneNr;
customer.gender = IntToEnum<customergenderType>((int)
person.gender);
return customer;
}
public static T IntToEnum<T>(int value)
{
return (T)Enum.ToObject(typeof(T), value);
}

This code was written knowing that person and customer use the same integer representations of male and female. The next example shows how this translation logic is applied on the message retrieved from the first service before sending it to the second. (Note that since this logic was written as an extension method it can be called as if it was a method of the person class.)

Example 3.
PersonServiceClient personService = new PersonServiceClient();
var aPerson = personService.GetPerson(2);
var customerFromPerson =
getPersonData.TransformPersonToCustomer();
CustomerServiceClient customerService = new
CustomerServiceClient();
customerService.UpdateCustomer(customerFromPerson);

LINQ-to-XML

Sometimes you may want to transform a type but you only need to transform a subset of the overall type. In those cases, deserializing a large document and building a large object graph can be wasteful and can make code more sensitive to future changes in data structures.

To handle this situation you can use LINQ-to-XML on the raw message that is returned from a service, as follows:

Example 4.
Message messageOut = channel.Request(messageIn);
XmlReader readResponse = messageOut.GetReaderAtBodyContents();
XmlDocument doc = new XmlDocument();
doc.Load(readResponse);
var xDoc = XDocument.Parse(doc.OuterXml);
XNamespace xmlns2 = xDoc.Root.Attribute("xmlns").Value;
var transformed = from d in xDoc.Descendants
(xmlns2 + "personElement")

select new Customer
{
firstName = d.Element(xmlns2 + "foreName").Value,
lastName = d.Element(xmlns2 + "surName").Value,
id = Convert.ToInt32(d.Element(xmlns2 + "id").Value),
gender = (Customer.genderType)
Enum.Parse(typeof(Customer.genderType),
d.Element(xmlns2 + "gender").Value),
phone = d.Element(xmlns2 + "address").
Element(xmlns2 + "phonenr").Value,
};

In this example, the response content from the message issued by the service is received; along with the namespace, the incoming XML structure is transformed into an object. Note that this code would continue to work even if the namespace of the response changes. The only change that can break this code is if one of the elements that are explicitly asked for is removed or has its name altered. An additional benefit of this approach is that we can process data types that are not otherwise easily handled in WCF, such as the xsd:choice construct.

XSLT Transformation

An option that is useful for avoiding deserialization is XSLT. By defining mapping logic with the XSLT language, we only take the data that we are interested in into our objects and leave the rest. XSLT can be used by different parts of the .NET platform and is a commonly supported industry standard, meaning that it may also be used with some legacy systems.

Here’s a sample XSLT transformation:

Example 5.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:b="http://schemas.example.org/enterprise/models/v1"
xmlns:a="http://schemas.example.org/enterprise/models/v2">
<xsl:template match="/">
<a:customerElement>
<a:id>
<xsl:value-of select="b:personElement/b:id"/>
</a:id>
<a:firstName>
<xsl:value-of select="b:personElement/b:foreName"/>
</a:firstName>
<a:lastName>
<xsl:value-of select="b:personElement/b:surName"/>
</a:lastName>
<a:phone>
<xsl:value-ofselect=
"b:personElement/b:address/b:phonenr"/>
</a:phone>
<a:gender>
<xsl:value-of select="b:personElement/b:gender"/>
</a:gender>
</a:customerElement>
</xsl:template>
</xsl:stylesheet>


The semantics of this transformation logic are quite straight forward in that the markup shows how to find the values for an element.

Using WCF, you could apply this XSLT transformation as follows:

Example 6.
Message messageOut = channel.Request(messageIn);
XmlReader readResponse = messageOut.GetReaderAtBodyContents();
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("XMLMessages/TransformationPersonToCustomer.xslt");
using (MemoryStream ms = new MemoryStream())
{
XmlWriterSettings ws = new XmlWriterSettings();
ws.Encoding = Encoding.UTF8;
using (XmlWriter xmlWriter = XmlWriter.Create(ms, ws))
{
xslt.Transform(readResponse, xmlWriter);
}
xmlWriter
}
Other -----------------
- Service-Orientation with .NET : Service Contracts and Interoperability - Canonical Schema
- Service-Orientation with .NET : Standardized Service Contract
- Cloud Services with Windows Azure : Windows Azure Storage
- A REST Service in Windows Azure
- Cloud Services with Windows Azure : A Web Service in Windows Azure
- Cloud Services with Windows Azure : Hello World in Windows Azure
- Cloud Services with Windows Azure : Windows Azure Roles
- Cloud Services with Windows Azure : Windows Azure Platform Overview
- Cloud Services with Windows Azure : Cloud Computing 101
- SOA with .NET and Windows Azure : Orchestration Patterns with WF - Compensating Service Transaction
 
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
 
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server