How to: Translate Between Business Entities and Service Entities

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies.
This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
To create client business applications using current Microsoft technologies, see patterns & practices' Prism.

Frequently, you have to translate between a business entity type used in the client to another entity type required by an external service. The Smart Client Application template includes an entity translator service in the Infrastructure.Library project. You can use this service to translate entities from one type to another. This topic describes how to use the implementation of the IEntityTranslatorService service.

Prerequisites

The steps in this topic assume that you have an existing smart client application. You can use the Smart Client Software Factory 2010 guidance package to quickly create the starting point for this how to topic.

Note

Note: The following procedure uses rootnamespace to refer to the root namespace that you used when you created your smart client solution. Replace rootnamespace with your application's root namespace.

To prepare a solution for this topic

  1. Install the Smart Client Software Factory 2010 Package.
  2. Use the Visual Studio template Smart Client Application to create the initial smart client solution. For information about how to create a solution with this template, see How to: Create Smart Client Solutions.
  3. Use the Add Business Module template to add a module to the Source solution folder. Name the module MyModule. For information about how to create a business module with this template, see How to: Create a Business Module.
  4. Create a new C# class library project in the Source solution folder and name it MyModule.ServiceProxies. This project will contain the service entity classes that MyModule will consume.
  5. Set the Default namespace property of the MyModule.ServiceProxies project to rootnamespace.MyModule.ServiceProxies. To do this, right-click MyModule.ServiceProxies in Solution Explorer, and then click Properties. Click the Application tab, and then enter rootnamespace.MyModule.ServiceProxies for the Default namespace property.

Steps

To translate between business entity types and service entity types, you have to implement code that performs the following tasks:

  1. Define the business and service entity types.
  2. Create an entity translator.
  3. Register the entity translator with the entity translator service.
  4. Use the service to translate entities.

The following procedures describe how to manually create the code that translates between entity types.

To define business and service entity types

  1. Create a class for a business entity in the BusinessEntities folder of the Infrastructure.Interface project. Name the class PhoneNumber. Different modules use this entity class and translate it to consume external services. By creating the class in the Infrastructure.Interface project, each module that references this project can use the entity definition.

  2. Replace the namespace and class declaration of the PhoneNumber class with the following code.

    namespace rootnamespace.Infrastructure.Interface.BusinessEntities
    {
      public class PhoneNumber
      {
        private string _number;
        private PhoneType _phoneType;
    
        public string Number
        {
          get { return _number; }
          set { _number = value; }
        }
    
        public PhoneType PhoneType
        {
          get { return _phoneType; }
          set { _phoneType = value; }
        }
      }
    
      public enum PhoneType
      {
        Home,
        Work,
        ,
      }
    }
    
  3. Add a new class file named MyModule.Proxies.cs to the MyModule.ServiceProxies project. This file will contain the implementations of your service entities. Service entities are defined in an external service that your application consumes and are tightly related to your business entities.

  4. Add the following service entity class definition to the MyModule.Proxies.cs file.

    Note

    Note: The following code is a simplified implementation of the PhoneNumber service entity defined in the BasicAccounts.Proxies.cs file in the BasicAccounts.ServiceProxies project of the Bank Branch Client reference implementation. Attributes were removed from this class definition for simplification. In this topic, only the entity fields are used in the entity translation.

    namespace rootnamespace.MyModule.ServiceProxies
    {
      public partial class PhoneNumber
      {
        private string phoneNumber1Field;
        private string phoneTypeField;
    
        public string PhoneNumber1
        {
          get { return this.phoneNumber1Field; }
          set { this.phoneNumber1Field = value; }
        }
    
        public string PhoneType
        {
          get { return this.phoneTypeField; }
          set { this.phoneTypeField = value; }
        }
      }
    }
    

Entity translators must implement the IEntityTranslator interface, defined in the Infrastructure.Interface project. This interface contains the four methods shown in the following code.

public interface IEntityTranslator
{
  bool CanTranslate(Type targetType, Type sourceType);
  bool CanTranslate<TTarget, TSource>();
  object Translate(IEntityTranslatorService service, Type targetType, object source);
  TTarget Translate<TTarget>(IEntityTranslatorService service, object source);
}

The Infrastructure.Library project contains two base classes for entity translators: EntityMapperTranslator and BaseTranslator. (The BaseTranslator class implements the IEntityTranslator interface.)

EntityMapperTranslator defines two generic types. These types correspond to the business entity type (TBusinessEntity) and to the service entity type (TServiceEntity). It provides default implementations for CanTranslate and Translate methods. The implementation of the Translate method calls the abstract methods BusinessToService and ServiceToBusiness. You must override these methods in your entity translator class.

protected abstract TServiceEntity BusinessToService(IEntityTranslatorService service, TBusinessEntity value);
protected abstract TBusinessEntity ServiceToBusiness(IEntityTranslatorService service, TServiceEntity value);

To create an entity translator

  1. Update the project references for the MyModule.ServiceProxies to include references to the Infrastructure.Interface and Infrastructure.Library projects. (The Infrastructure.Interface project contains the business entity class, and the Infrastructure.Library project contains the base classes for your entity translator class.)

  2. Create a new folder named EntityTranslators in the MyModule.ServiceProxies project. Add a new class named PhoneNumberTranslator to this folder.

  3. Add the following using statements to this class.

    using rootnamespace.Infrastructure.Interface.Services;
    using rootnamespace.Infrastructure.Library.EntityTranslators;
    
  4. Change the class declaration to inherit from the EntityMapperTranslator class, and use your business and service entity types for the type parameters, as shown in the following code.

    public class PhoneNumberTranslator : EntityMapperTranslator< rootnamespace.Infrastructure.Interface.BusinessEntities.PhoneNumber, PhoneNumber>
    
  5. Implement the BusinessToService method. This method translates a business entity object into a service entity object. The following code is an example implementation of this method.

    protected override PhoneNumber BusinessToService(IEntityTranslatorService service, rootnamespace.Infrastructure.Interface.BusinessEntities.PhoneNumber value)
    {
      PhoneNumber result = new PhoneNumber();
      result.PhoneNumber1 = value.Number;
      result.PhoneType = value.PhoneType.ToString();
      return result;
    }
    
  6. Implement the ServiceToBusiness method. This method translates a service entity object to a business entity object. The following code is an example implementation of this method.

    protected override rootnamespace.Infrastructure.Interface.BusinessEntities.PhoneNumber ServiceToBusiness(
    IEntityTranslatorService service, PhoneNumber value)
    {
      rootnamespace.Infrastructure.Interface.BusinessEntities.PhoneNumber result =
        new rootnamespace.Infrastructure.Interface.BusinessEntities.PhoneNumber();
      result.Number = value.PhoneNumber1;
      if (value.PhoneType != null)
        result.PhoneType =
          (rootnamespace.Infrastructure.Interface.BusinessEntities.PhoneType)
          Enum.Parse(typeof(rootnamespace.Infrastructure.Interface.BusinessEntities.PhoneType), value.PhoneType);
      return result;
    }
    

To register the entity translator with the entity translator service

  1. Update the project references for the MyModule project to include references to the MyModule.ServiceProxies and Infrastructure.Library projects.

  2. Add the following using statements to the Module.cs file of the MyModule project.

    using rootnamespace.Infrastructure.Interface.Services;
    using rootnamespace.MyModule.ServiceProxies.EntityTranslators;
    
  3. Override the AddServices method. In this method, retrieve the IEntityTranslatorService from the root WorkItem, and use this service to register the PhoneNumberTranslator.

    Note

    Note: When the application starts, it adds an instance of the IEntityTranslatorService to the root WorkItem. The AddServices method of the SmartClientApplication class located in the Infrastructure.Library project contains the code add the service to the root WorkItem.

    public override void AddServices()
    {
      base.AddServices();
      RegisterTranslators();
    }
    
    private void RegisterTranslators()
    {
      IEntityTranslatorService translator = _rootWorkItem.Services.Get<IEntityTranslatorService>();
      translator.RegisterEntityTranslator(new PhoneNumberTranslator());
    }
    

Note

Note: The following procedure uses a class named MyService as a representation of a complex service that consumes the IEntityTranslatorService to translate entities.
The Bank Branch Client reference implementation contains multiple implementations of services that use the entity translator service. For examples, see the files in the Services folder of the BranchSystems.Module project.

To translate entities

  1. Add a new class to the Services folder of the MyModule project. Name the class MyService. Add the Service attribute ([Service]) to the class declaration, as shown in the following code.

    [Service]
    public class MyService
    {
    }
    
  2. Add the following using statements to the class file.

    using rootnamespace.Infrastructure.Interface.BusinessEntities;
    using rootnamespace.Infrastructure.Interface.Services;
    using Microsoft.Practices.CompositeUI;
    
  3. Create a reference to IEntityTranslatorService, and create a public property with the ServiceDependency attribute. ObjectBuilder will use this attribute to inject the IEntityTranslatorService into the service when the application creates the service.

    private IEntityTranslatorService _translator = null;
    
    [ServiceDependency]
    public IEntityTranslatorService Translator {
      get { return _translator; }
      set { _translator = value; }
    }
    
  4. Create a method named TranslatePhoneNumber in the MyService class (you can choose any name for the method). In this method, call the Translate method of the IEntityTranslatorService service to translate between entity object types. The following code demonstrates how to translate between a business entity object and a service entity object. (The code assumes that you have an existing business entity object.)

    // Translate a business entity to a service entity.
    rootnamespace.MyModule.ServiceProxies.PhoneNumber serviceEntity = Translator.Translate< rootnamespace.MyModule.ServiceProxies.PhoneNumber>(businessEntity);
    

For multiple examples of how to translate entities, see the classes in the Services folder of the BranchSystems.Module project in the Bank Branch Client reference Implementation.

Outcome

At the conclusion of this topic, you will have the following elements:

  • A business entity and a service entity
  • An entity translator for the defined entities
  • A module that registers the entity translator with the entity translator service
  • A service that consumes the entity translator service and uses that service to translate entities from one type to another

Next Steps

After translating business entities and services entities, you typically write code to show the business entities in the UI. For guidance about how to map business entities to UI elements, see How to: Map Business Entities to User Interface Elements.

Note

Note: If you invoked the Web service asynchronously—that is, if you used the Disconnected Service Agent Application Block—you will need to implement the UI Threading pattern.