2009-03-21 2 views
1

У меня проблема с WCF. Я думаю, что понимаю, в чем проблема, но мне нужно , чтобы проверить это понимание и спросить, видел ли кто-нибудь это раньше или может предложить обходной путь или альтернативный подход. Пожалуйста, несите меня: это значительная проблема , которую трудно сломать до минимального тестового примера.столкновение типа WCF

Проблема: Я пишу интерфейс C# к устаревшей системе обмена сообщениями. У меня реализована сборка interop для прямого интерфейса и все работает нормально. Основой этого является то, что у меня есть класс для каждого типа сообщения, а общий класс для прохождения, который просто занимает то же место, что и сообщение максимального размера.

Каждый класс сообщений реализует операторы литья, которые должны быть введены в этот класс , называемый QOD_Message. Общий класс и индивидуальное сообщение классы являются производными от минимального класса сообщений bodyless. Клиентское приложение C# , желающее отправить сообщение, просто вызывает метод отправки в сборке интерфейса, который принимает QOD_Message, кастинг в общий тип для отправки. Событие приемника передает приёмному приложению C# общий тип, который следует отличать в соответствии с общим членом , который имеет взаимно-однозначное отношение с типом сообщения.

Я реализовал сборку локального прямого интерфейса, и все это прекрасно работает , и теперь я могу отправить сообщение между тестовым приложением C# и существующими приложениями . Замечательно. Основная структура класса выглядит так:

public class QOD_Message_Minimal 
{ 
    a message header 
} 

public class QOD_Message : QOD_Message_Minimal 
{ 
    generic message - defines an empty body 
} 

public class QOD_WcfDialout : QOD_Message_Minimal 
{ 
    ... some irrelevant code 

    // cast operators to convert to and from the abstract message class. 

    public static implicit operator QOD_Message (QOD_WcfDialout m) 
    { 
     ... some irrelevant code 
    } 

    public static implicit operator QOD_WcfDialout (QOD_Message m) 
    { 
     ... some irrelevant code 
    } 
} 

Обратите внимание на операторы литья.

Теперь возникает проблема. Я хочу расширить этот интерфейс для поддержки WCF, поэтому другая группа разработчиков за рубежом может связываться через WCF с помощью адаптера Служба WCF, которую я написал. Это называется, с замечательным отсутствием воображения, WCF_Adapter, . WCF_Adapter предоставляет для тестовых целей один метод , который принимает строку (Dialout) и преобразует ее в сообщение для устаревшего кода. Это также отлично работает с вызовом функции в моем приложении WCF_Client, которое преобразуется в устаревшее сообщение и отправляется получателю (фиксированный).

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

[ServiceContract] 
public interface IDialout 
{ 
    [OperationContract (IsOneWay = true)] 
    void Dialout (string NumberToDial); 

    [OperationContract (IsOneWay = true)] 
    void Dispatch (QOD_Message msg); 
} 

Так что я продлил клиент и сервис WCF_adapter, генерируя мой прокси-код для клиента WCF и .... Ох. Клиент не будет компилироваться.

Похоже, что клиентское приложение не может понять оператора литья и выбрасывает ошибку компиляции .Даже если я включу сборку сообщений с кодом выше в качестве ссылки, клиентский код «предпочитает» тип, определенный в сгенерированном прокси-сервере , и игнорирует исходный тип сообщения, поэтому он не может «видеть» листинг, а не будет компиляции. Это ошибка:

предупреждение CS0436: Тип 'QOD_Messaging.QOD_Message' в конфликтов 'бла-бла \ generatedProxy.cs' с импортированной типа 'QOD_Messaging.QOD_Message' в «бла-бла \ QOD_Messaging. длл. Используя тип, определенный в 'blah-blah \ generatedProxy.cs'.

Насколько я могу судить, класс, определенный в сгенерированном прокси, является правильным, , но, конечно, сгенерированный прокси-класс определяет только члены данных, а не функциональность. Он содержит два класса

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")] 
[System.Runtime.Serialization.DataContractAttribute(Name="QOD_Message_Minimal", Namespace="http://schemas.datacontract.org/2004/07/QOD_Messaging")] 
[System.Runtime.Serialization.KnownTypeAttribute(typeof(QOD_Messaging.QOD_Message))] 
public partial class QOD_Message_Minimal : object, System.Runtime.Serialization.IExtensibleDataObject 
{ 
    whole slew of data members. 
} 

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")] 
[System.Runtime.Serialization.DataContractAttribute(Name="QOD_Message", Namespace="http://schemas.datacontract.org/2004/07/QOD_Messaging")] 
public partial class QOD_Message : QOD_Messaging.QOD_Message_Minimal 
{ 
    extra stuff to define the added body. 
} 

Так .....

я могу оставить ссылку на сборку, так что код не может увидеть бросок и не компилировать, или я могу оставить ссылка in и компилятор умышленно игнорирует определение типа сборки и использует определение прокси-сервера ... и не скомпилируется.

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

ответ

1

Операторы преобразования не являются частью генерируемого mex, поэтому они не будут существовать на клиенте.

Учитывая сложность здесь - можно ли использовать совместное использование сборок? то есть вместо генерируемых (прокси) типов, можете ли вы ссылаться на исходную сборку для типов? Это поддерживается как в среде IDE (в диалоговом окне «Дополнительно», хотя по умолчанию она включена, поэтому может работать уже, если у вас есть ссылка на сборку с типами сообщений) и через svcutil (переключатель/r). Затем у вас есть свои оригинальные типы, включая конверсии, у клиента.

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

+0

Отлично - я не думал использовать флаг/r, будучи ужасным новичком в этом C# lark. Это сделал трюк. Большое спасибо. –

1

Единственным видом класса, который может быть открыт в веб-службе, является метод. Свойства, операторы, ролики, индексы, делегаты, события и все остальное могут быть раскрыты.

Напомним, что односторонний или антуражный веб-сервис описывается одним или несколькими документами XML: WSDL, XML Schema, WS-Policy и т. Д. Ни один из этих документов не имеет возможности описать любые операторы языка программирования любого типа, включая операторы литья.

Можно использовать методы класса в качестве операторов веб-сервисов, а также предоставлять классы в виде контрактов на передачу данных или контрактов на неисправности, которые должны отображаться как схема XML и контракты с сообщениями, которые должны отображаться как типы сообщений. Ничто другое не может быть раскрыто.

+1

«метод» .... –

+0

Спасибо, и в следующий раз просто отредактируйте его самостоятельно. –

Смежные вопросы