среда, 17 августа 2011 г.

Взаимодействие с веб службами и пересекающимися типами данных

Недавно коллега столкнулся с интересной задачей: есть две службы с идентичными (пересекающимися) типами данных (пример ниже).

Необходимо было работать с обоими экземплярами этих типов на клиентской стороне, не зная о их конкретной принадлежности к той или иной службе.

Решение было довольно простым, но раз оно вызвало вопросы, решил его опубликовать.

Ключевые слова: partial классы, интерфейсы, dynamic.

Например, у нас есть служба WebService1, у которой метод GetCustomer возвращает экземпляр типа Customer.
Пример кода службы:

public class WebService1 : WebService {

    [WebMethod]
    public Customer GetCustomer(int id) {
        return new Customer
        {
            Id = id,
            Name = "test"
        };
    }
}


Описание типа Customer на стороне службы:

public class Customer
{
    public int Id { get; set; }

    public string Name { get; set; }

    public Customer()
    {
    }
}

 И есть служба WebService2 с точно таким же методом и типом возвращаемого значения.

Первый вариант решения.

Если вы используете .Net Framework 4.0, то можете воспользоваться утиной типизацией с помощью типа dynamic.
Например:
dynamic dynamicCustomer1 = service1.GetCustomer(1);
DoWork(dynamicCustomer1);

...

private void DoWork(dynamic customer)
{
     Console.WriteLine(customer.Name);
}

Второй вариант решения.

Объявить общий интерфейс ICustomer, который должны реализовать типы Customer обеих служб. Это можно сделать на клиентской стороне благодаря тому, что эти типы автоматически генерируются в виде partial классов.
Пример:

namespace WebServiceClient
{
    public interface ICustomer
    {
        int Id { get; set; }
        string Name { get; set; }
    }
}

namespace WebServiceClient.WebService1
{
    public partial class Customer : ICustomer
    {
    }
}

namespace WebServiceClient.WebService2
{
    public partial class Customer : ICustomer
    {
    }
}
...

Использование:

ICustomer customer1 = service1.GetCustomer(1);
DoWork(customer1);

...

private void DoWork(ICustomer customer)
{
       Console.WriteLine(customer.Name);
}



Комментариев нет:

Отправить комментарий