Remoting или WCF для новой разработки (между двумя .NET-приложениями на одном компьютере) с использованием интерфейсов?

Мы хотим, чтобы два приложения .NET, работающие на одном компьютере, обменивались данными друг с другом. Мы хотим три проекта. Библиотека, содержащая интерфейсы. Приложение "сервер", которое реализует интерфейсы и "клиентское" приложение, которое взаимодействует с сервером с использованием интерфейсов. Мы не хотим, чтобы клиент ссылался на сервер.
У нас есть тестовое приложение, которое делает это с удалением, но недавно обнаружило, что удаленное соединение заменяется WCF. Поскольку это новая разработка, мы считаем, что мы должны использовать WCF, но нам не удалось заставить ее работать с WCF и задавались вопросом, возможно ли это?


EDIT:

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

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

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

Оба сборки ServiceApp и ClientApp ссылаются на сборку Lib. Они не ссылаются друг на друга.

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


EDIT:

Ниже приведена упрощенная версия тестового кода для WCF.

Следующая строка из ClientProgram генерирует исключение:

IMessage msg2 = service.CreateMessage("Hello World");

Вот исключение:

Could not load file or assembly 'ServiceApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

EDIT:

В попытке понять последний комментарий Стивена я искал IMetadataExchange, который, конечно же, впервые попал на страницу Публикация метаданных.

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

Мне удалось добавить ссылку на службу после небольшой работы. Служба должна быть запущена, но если вы запустите службу через Visual Studio, у вас нет возможности добавить ссылку на службу. Кроме того, я до сих пор не понимаю, как должна работать опция "Discover Services in Solution". В итоге мне удалось добавить ссылку, открыв папку bin/debug, чтобы вручную запустить службу, а затем ввести URL-адрес, который я добавил в мое служебное приложение. Если это правильный путь, это довольно неудобно.

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

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

Теперь, когда я пытаюсь запустить его, я получаю следующую ошибку в строке 4:

The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:msg. The InnerException message was 'XML 'Element' 'http://tempuri.org/:msg' does not contain expected attribute 'http://schemas.microsoft.com/2003/10/Serialization/:Type'. The deserializer has no knowledge of which type to deserialize. Check that the type being serialized has the same contract as the type being deserialized.'.  Please see InnerException for more details.

EDIT:

Один день ушел на щедрость и никаких ответов, так как я добавил щедрость. Есть ли что-нибудь, что я могу прояснить, пока не наступит время награды?


EDIT:

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

Ответ 1

У Remoting есть некоторые прецеденты, такие как связь между доменами приложения в рамках одного процесса. Сказав это, да, WCF - это путь. Однако из некоторых вещей, о которых вы сказали, я не уверен, понимаете ли вы, как это должно работать.

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

Ответ 2

WCF - это путь, в частности, проверить привязку Net Named Pipe с WCF. Это обеспечит очень быструю межпроцессную связь на одном компьютере.

Если ваш таргетинг на Windows Server 2008 для вашего производственного развертывания, вы можете использовать IIS 7 в качестве среды размещения. Проверьте Расширьте свои службы WCF за пределами HTTP с WAS.

Существует много информации о запуске типа WCF. Выезд:

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

Ответ 3

Используется как.

Определенно идти с WCF.

Демонстрация плохо документирована и обидчива. WCF намного проще для сравнения. Не уверен, что у вас есть проблемы, но там есть много документов на WCF.

Ответ 4

Я только что переключил программу из удаленного доступа в WCF, и я столкнулся с множеством вещей, которые обычно выполнялись без проблем при удалении, но это вызывает проблемы в wcf:

  • Класс CallContext отсутствует. Я использовал это для передачи некоторой информации о, например. выбранный язык и некоторая информация о пользователе. С WCF мне пришлось создать MessageInspector для добавления заголовков с этой информацией в каждый запрос.
  • Исключения больше не передаются без изменений. Вместо этого вам нужно использовать FaultException и FaultContracts.
  • Прокси не кажутся такими же легкими. Мне нужно распоряжаться ими, а не просто оставлять их для сбора мусора, иначе моя служба будет висеть. (На самом деле это даже не так просто, как вызвать Dispose для правильного завершения прокси-сервера, вам нужна довольно сложная последовательность try, catch, наконец, которая вызывает Close и Abort для разных типов исключений.) Необходимость закрытия прокси вызывает немного проблемы, когда я хочу, чтобы моя платформа IoC управляла прокси-серверами.

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

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

Ответ 5

Вот один пример, который нужно сделать с помощью Remoting-like с WCF:

  • 3 проекта: сервер, клиент, shared.dll
  • сервер и клиент обе ссылки shared.dll
  • поместите сервисный интерфейс с [ServiceContract] в shared.dll
  • добавить класс реализации службы в сервер
  • не используйте интерфейсы для ваших типов данных
  • создавать типы голосовой кости DataContract только с логикой, которую вы хотите совместно использовать между клиентом и сервером (например, проверка)
  • поместите ваши типы данных DataContract в shared.dll
  • Не используйте NetDataContractSerializer (как будто вы делаете в своем коде)

Конечно, существуют вариации на эту тему. Например. вместо общей dll вы можете совместно использовать файлы кода между серверными и клиентскими проектами С#if для различной компиляции.