У меня есть несколько услуг WCF, которые разделяют некоторые контракты данных и должны сгенерировать клиентский код, используя svcutil.exe. Я столкнулся с ошибками, используя два самых очевидных способа сделать это и нуждаться в некоторой помощи.
Но сначала, вот услуги:
[ServiceContract( Namespace = "http://www.me.com/services/" )]
public interface IFooService {
[OperationContract]
Response RunFoo( Request request );
}
[ServiceContract( Namespace = "http://www.me.com/services/" )]
public interface IBarService {
[OperationContract]
Response RunBar( Request request );
}
Ответ и Запрос определены на отдельном собрании:
[DataContract( Namespace = "http://www.me.com/shared/" )]
public class Request {
[DataMember]
public int Input { get; set; }
}
[DataContract( Namespace = "http://www.me.com/shared/" )]
public class Response {
[DataMember]
public int Result { get; set; }
}
Услуги осуществлены некоторым тривиальным способом, собранным, изданным - давайте переключимся на сторону клиента теперь.
Включая обе услуги на svcutil командную строку - как это:
svcutil /o:Client.cs http://hostname.com/FooService.svc http://hostname.com/BarService.svc
приведет к многочисленным сообщениям об ошибках о дублированных типах данных, начиная с
Ошибка: была ошибка проверки на схеме, произведенной во время экспорта: Источник: Линия: 1 Колонка: 9 087 Ошибок Проверки: глобальный элемент 'http://schemas.microsoft.com/2003/10/Serialization/:anyType' был уже объявлен.
и окончание
Ошибка: была ошибка проверки на схеме, произведенной во время экспорта: Источник: Линия: 1 Колонка: 12 817 Ошибок Проверки: complexType 'http://www.me.com/shared/:Response' был уже объявлен.
Создание клиентского файла отдельно для каждого обслуживания избегает этих ошибок:
svcutil /o:Foo.cs http://hostname.com/FooService.svc
svcutil /o:Bar.cs http://hostname.com/BarService.svc
Но тогда определения общих типов (такие как Запрос и Ответ) будут дублированы в Foo.cs и затем в Bar.cs, приводя, очевидно, к ошибкам компилятора.
Так, что обычный путь состоит в том, чтобы сгенерировать клиентский код, поглощающий такие услуги?
Ограничения:
Ну, в основном вы можете
Или тогда:
, либо вы могут Поделитесь общим собранием - или вы не могут - я не вижу другого выбора, правда.
Поскольку у вас есть правила общий сборник Dто (почему, кстати?), Самый простой вариант в этом случае выглядит , чтобы генерировать типы в различных пространствах имен C # (т.е. два звонка на Svcutil
) и сопоставьте данные между двумя. По сути: лечить DTO из двух услуг по совпадению, подобно аналогичном.
Вы можете использовать такие вещи, как Automapper, чтобы уменьшить работу, или вы можете шутить сериализовать от типа a и десериализовать на тип B (при условии, что фактические данные пространства имен и т. Д.
Когда вы запустите клиентскую утилиту один раз, вы получите файл XXXXService.cs и output.config.
Если вы наблюдаете за классом XXXXService, у вас есть все в файле. Вы можете разделить их как отдельные файлы IXXXService и XXXService и файл datacontracts.
Затем вы можете запустить утилиту для второй службы и добавить файлы IXXXService1.cs и 1XXXService.cs и те же самые контракты данных, которые вы можете использовать для совместного использования для этих 2.
Я не уверен, что это может ответить на ваш вопрос. У меня был пример , который может вам помочь. Вы можете увидеть еще несколько примеров здесь , связанных с некоторыми материалами MVC и WCF.
WSCF Blue может приблизить вас к решению, если вы его еще не нашли.
Он может создавать отдельные файлы для каждого типа, перезаписывая их при последующих операциях.