Работа с параллельными и сложными службами WCF, взаимодействующими с объектами всего приложения - PullRequest
4 голосов
/ 17 мая 2011

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

Хорошо, рассмотрим этот фрагмент кода, определяющий сервис и использующий его.(нет упоминания о конечных точках, которые определены в app.config, здесь не показано):

[ServiceContract]
public interface IMyService {
   [OperationContract]
   string Operation1(int param1);
   [OperationContract]
   string Operation2(int param2);
}

public class MyService : IMyService {
   public string Operation1(int param1) { ... }
   public string Operation2(int param2) { ... }
}

public class Program {
   public static void Main(stirng[] args) {
      using (ServiceHost host = new ServiceHost(typeof(MyService))) {
         host.Open();
         ...
         host.Close();
      }
   }
}

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

Список, о котором я говорю, представляет собой список, управляемый программой и редактируемый и модифицируемый ею.

У меня естьследующие вопросы:

1) Как создать сервис, способный обработать этот список?Я знаю, что возможный вариант - использование перегруженного конструктора ServiceHost, принимающего Object вместо службы Type.Так что я мог бы передать свой список там.Это хорошо?

[ServiceContract]
public interface IMyService {
   [OperationContract]
   string Operation1(int param1);
   [OperationContract]
   string Operation2(int param2);
}

public class MyService : IMyService {
   private List<> myinternallist;
   public MyService(List<> mylist) {
      // Constructing the service passing the list
   }
   public string Operation1(int param1) { ... }
   public string Operation2(int param2) { ... }
}

public class Program {
   public static void Main(stirng[] args) {
      List<> thelist;
      ...
      MyService S = new MyService(thelist)
      using (ServiceHost host = new ServiceHost(S)) {
         host.Open();
         ...
         host.Close();
         // Here my application creates a functions and other that manages the queue. For this reason my application will edit the list (it can be a thread or callbacks from the user interface)
      }
   }
}

Этот пример должен проясниться.Это хороший способ сделать?Я правильно делаю?

2) Как обрабатывать конфликты на этом общем ресурсе между моей службой и моим приложением?Когда мое приложение запускается, размещая сервис, мое приложение может вставлять элементы в список и удалять их, то же самое можно сделать и с сервисом.Нужен ли мне мьютекс?как справиться с этим?Обратите внимание, что проблема параллелизма касается двух участников: основного приложения и службы.Это правда, что сервис одноразовый, но приложение действует в списке !!!Я предполагаю, что служба вызывается внешним объектом, когда это происходит, приложение все еще работает правильно?Есть ли параллелизм в этом случае ???

Спасибо

Ответы [ 2 ]

1 голос
/ 17 мая 2011

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

Я бы посмотрел на контейнер инжектора зависимостей (DI) , чтобы WCF делал то, что вы пытаетесь сделать.Позвольте контейнеру DI предоставить экземпляр единого списка вашим сервисам.@ Smudge202 также абсолютно прав, что для реализации списка вам необходимо использовать функциональность Concurrent Collection.

ОБНОВЛЕНИЕ, основанное на ветке комментариев:

Подход DI будет работать путем получения всехзависимости объекта от контейнера DI вместо того, чтобы создавать их вручную в коде.Вы регистрируете все типы, которые будут предоставлены контейнером при запуске приложения.Когда приложению (или WCF) требуется новый экземпляр объекта, оно запрашивает его из контейнера, а не «обновляет» его.Например, библиотека интеграции Castle Windsor в Castle реализует всю проводку, необходимую для предоставления WCF экземпляра службы из контейнера.В этих публикациях объясняется, как использовать контейнер Microsoft Unity DI с WCF, если вы хотите выполнить собственную интеграцию с WCF.

Общий список, указанный в этом вопросе, будет зарегистрирован вКонтейнер как уже созданный объект из вашего приложения.Когда экземпляр службы WCF запускается из контейнера DI, будут предоставлены все параметры конструктора, включая ссылку на общий список.Существует много информации о внедрении зависимостей и инверсии управления, но эта статья Мартина Фаулера - хорошее место для начала.

1 голос
/ 17 мая 2011

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

Я не уверен, что вы подразумеваете под пунктом 1. Звучит как выВы описываете базовый полиморфизм , но, возможно, вы могли бы уточнить на примере, пожалуйста?

РЕДАКТИРОВАТЬ: В ответ на комментарии, которые вы сделали к ответу Sixto, рассмотрите возможность использования сеансов WCF .Из того, что вы описали, мне кажется, что служба WCF должна находиться в отдельном хост-приложении.Приложение, которое вы используете в настоящее время, должно иметь ссылку на службу для службы, и использование сеансов сможет вызвать операцию, имитирующую ваше требование для создания экземпляра службы со списком, определенным текущим клиентским приложением.

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

Надеюсь, это достаточно хорошо объяснено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...