Две службы WCF с разными контрактами, но с одинаковыми бизнес-объектами - PullRequest
6 голосов
/ 23 июня 2009

Например, у меня есть две службы, размещенные в IIS.

[ServiceContract]
public interface IDeviceService
{
    [OperationContract]
    DeviceCollection GetAllDevices(Customer customer);

}

[ServiceContract]
public interface IUserService
{
    [OperationContract]
    User Authenticate(string username, string password);

}

Как объект User, возвращаемый из операции Authenticate в UserService, так и DeviceCollection, возвращаемый из операции GetAllDevices в DeviceService, имеют определение дочернего объекта Customer. Клиент - это бизнес-объект, находящийся в той же сборке, что и объекты «Пользователь» и «Устройство».

Моя проблема на клиенте - когда я вызываю работу устройства

userProxy.GetAllDevices(user.Customer);

Компилятор жалуется следующим сообщением:

Аргумент 1 - Невозможно преобразовать из UserService.Customer в DeviceService.Customer

Я могу нормально подключиться к обеим службам, проблема заключается в определении объекта Customer. Я действительно не хочу помещать Операции в один и тот же сервис, поскольку они, кажется, живут в своих собственных сервисах. Я думаю, что я спрашиваю, как другие программисты справляются с такой проблемой?

Ура, Стюарт

Ответы [ 4 ]

3 голосов
/ 23 июня 2009

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

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

2 голосов
/ 21 июля 2009

Одним из вариантов будет использование AutoMapper на клиенте для плавного преобразования из одного типа в другой. Поскольку они имеют одинаковые свойства, сопоставления будут простыми.

0 голосов
/ 25 июня 2009

Это семантическая проблема. Если вы хотите определить один UserService.Customer и DeviceService.Customer как семантически равные, то вы должны физически повторно разложить этот контракт данных в отдельную сборку. В качестве альтернативы, если вы хотите определить UserService.Customer и DeviceService.Customer как семантически разные, то оставьте их как отдельные типы и напишите служебную функцию для перевода из одного в другой.

0 голосов
/ 25 июня 2009

Я подумал, что попытаюсь ответить на свой вопрос с подробностями о том, как я решил это решение. Он был основан на статье в блоге Дэна Майнека .

Это резюме, я думаю, что моя концепция наличия нескольких сервисов для каждого из моих корневых бизнес-объектов была неверной.

Вместо этого я предоставил один сервис, который реализовал несколько DataContracts, например

public partial class DeviceService : IDeviceService, IUserService
{
}

Поскольку служба устройств создана как частичный класс, это позволило мне разделить службы, ну, я говорю, что они раздельные, это все та же служба, но это позволило мне разделить их на отдельные файлы и придать службе некоторую структурную организацию.

Последним этапом реализации было объявление двух конечных точек в определении сервиса, например

<service behaviorConfiguration="GPSCloudHost.DeviceServiceBehavior" name="BusinessService.DeviceService">
<endpoint address="Device" binding="wsHttpBinding"   contract="BusinessService.DataContracts.IDeviceService"></endpoint>
    <endpoint address="User" binding="wsHttpBinding"   contract="BusinessService.DataContracts.IUserService"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

У меня недостаточно опыта в WCF, чтобы сказать, является ли это "правильным" решением или нет, но оно работает для моих требований. Если у кого-то есть лучшее решение, я бы с удовольствием его услышал!

Приветствия

...