Как обеспечить выполнение контрактов потока транзакций WCF с двумя службами в одном проекте? - PullRequest
1 голос
/ 20 декабря 2009

Я только что прочитал фантастическую статью о транзакциях и потоке WCF. В значительной степени оставил мне только один без ответа вопрос:

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

ServiceA.svc

   [OperationBehavior(TransactionScopeRequired = true)]
   OperationA()


ServiceB.svc

  [OperationBehavior(TransactionScopeRequired = true)]
  OperationB()

OperationA() необходимо позвонить OperationB().

Я могу довольно легко просто сказать new ServiceB().OperationB(...) изнутри ServiceA (помните, я сказал, что они находятся в одном веб-проекте, работающем на одном сервере.

Сначала я подумал, что это то, что я буду делать, но я не уверен, что все транзакции будут испорчены или нет - особенно если контракты на транзакции отличались между двумя операциями. Очевидно, что если я получу доступ к Transaction.Current из OperationB, он будет существовать, но если бы две операции имели разные контракты (как описано в указанной статье), правила не были бы соблюдены.

Как правильно ServiceA.OperationA() звонить ServiceB.OperationB()?

(Интересно также, как это сделать, когда одна операция вызывает другую в том же классе, но это, вероятно, проще для Google)

1 Ответ

1 голос
/ 20 декабря 2009

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

Таким образом, в вашем случае, если вы хотите вызвать ServiceB из ServiceA, вы должны создать клиентский прокси для ServiceB внутри ServiceA и вызвать ServiceBClientProxy.OperationB() на этом клиентском прокси.

Вы можете создать прокси клиента несколькими способами:

  • через диалоговое окно «Добавить ссылку на службу» в Visual Studio, которое под крышками просто вызывает утилиту командной строки svcutil.exe, которую также можно вызвать напрямую. Это создает хорошие прокси и все, но ужасные конфиги

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

По сути, вам нужен экземпляр ChannelFactory<T> для контракта на обслуживание вашего ServiceB, а затем вы вызываете метод CreateChannel() на этой фабрике каналов, чтобы получить фактический канал (= прокси-клиент клиента) для этой услуги. Примерно так:

 ChannelFactory<IServiceB> factory = new ChannelFactory<IServiceB>();
 IServiceB clientProxy = factory.CreateChannel();

Это берет все детали из web.config - если вы хотите, вы можете определить привязки и конечные точки в коде и передать их в конструктор для ChannelFactory.

Теперь у вас есть клиентский прокси для ServiceB, и вы можете вызывать все его методы. Это правильный способ сделать это в WCF.

Надеюсь, это немного поможет!

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