• Microsoft .NET
  • WPF и Silverlight
  • Синхронные вызовы веб-службы в Silverlight: Развенчание мифа об исключительной асинхронности

Создание бизнес-приложений с помощью Silverlight - Преобразование объектов сообщения

ОГЛАВЛЕНИЕ

Преобразование объектов сообщения

Кроме этого, метод GetAgentScriptCallback преобразует объекты выходного сообщения (известные также как DataContracts) из службы в объект клиентской стороны, представляющий обычную семантику клиентской стороны. Например, при проектировании объектов сообщений серверной стороны можно не заботиться о привязке данных, обращая при этом внимание на то, что по своей природе служба используется многократно и должна предусматривать широкий диапазон применений, а не только центр обработки вызовов.

Помимо этого разумно избегать тесной связи с объектами сообщения, поскольку у клиента не будет возможности контролировать изменения объектов сообщений. Методика преобразования объектов сообщения в объекты клиентской стороны не применима напрямую к Silverlight, но в общем случае может быть применена к любому потребителю веб-службы, если требуется избежать тесной связи на этапе проектирования.
Я принял решение сделать реализацию преобразователей объектов крайне простой — никаких экзотических вложенных обобщенных типов, лямбда-выражений или инверсий контейнеров элементов управления. ClientEntityTranslator является абстрактным классом, определяющим метод ToClientEntity(), который каждый подкласс должен переопределять.

public abstract class ClientEntityTranslator
{
  public abstract ClientEntities.ClientEntity ToClientEntity(object 
  serviceOutputEntity);
}

Каждый дочерний класс является уникальным для типа обмена между службами; следовательно, я буду создавать столько преобразователей, сколько потребуется. В моем демонстрационном примере имеется три типа вызовов служб: IUserProfile.GetUser(), ICallService.GetAgentScript() и ICallService.GetOrderDetails(). Поэтому я создал три преобразователя, как показано на рис. 6.

Рис. 6 Преобразователь объекта сообщения в объект клиентской стороны

public class SvcOrderToClientOrder : ClientEntityTranslator
{
  //singleton
  public static ClientEntityTranslator entityTranslator = new  
  SvcOrderToClientOrder();
  private SvcOrderToClientOrder() { }
  public override ClientEntities.ClientEntity ToClientEntity(object  
  serviceOutputEntity)
  {
  CallBusinessProxy.OrderInfo oi = serviceOutputEntity as 
  CallBusinessProxy.OrderInfo;
  ClientEntities.Order bindableOrder = new ClientEntities.Order();
  bindableOrder.OrderNumber = oi.Order.OrderNumber;
  //code removed for brevity ... 
  return bindableOrder;
  }
}

public class SvcUserToClientUser : ClientEntityTranslator
{
  //code removed for brevity ... 
}

public class SvcScriptToClientScript : ClientEntityTranslator
{
  //code removed for brevity ...
  }
}

Если вы обратили внимание, вышеприведенные преобразователи имеют неизменное состояние и используют единственный шаблон. Из соображений согласованности преобразователь должен быть в состоянии наследовать классу ClientEntityTranslator и он должен быть singleton-классом во избежание попадания сборщику мусора.

Я постоянно использую один и тот же экземпляр при любом вызове соответствующей службы. Можно было бы также создать ServiOutputEntityTranslator для взаимодействия служб, которое требует больших входных сообщений (обычно так бывает в случае вызова транзакционной службы), с помощью следующего определения класса.

public abstract class ServiOutputEntityTranslator
{
  public abstract object ToServiceOutputEntity(ClientEntity  
  clientEntity);
}

Если вы обратите внимание на значение, возвращаемое упомянутой выше функцией, то увидите, что это «object», поскольку я не управляю базовым классом объектов сообщения (это было бы возможно в данном демонстрационном примере, но не в реальной ситуации). Безопасность типа будет реализована соответствующими преобразователями. Для упрощения демонстрационного примера я не сохраняю никакие данные на сервере, поэтому в данный пример не входят никакие преобразователи объектов клиента в объекты сообщения.