Как получить ссылку на объект службы WCF из кода, который его создает? - PullRequest
3 голосов
/ 25 февраля 2009

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

Класс сервера в учебнике создан с использованием следующего кода:

class Program
  {
    static void Main(string[] args)
    {
      using (ServiceHost host = new ServiceHost(
        typeof(StringReverser),
        new Uri[]{
          new Uri("net.pipe://localhost")
        }))
      {

        host.AddServiceEndpoint(typeof(IStringReverser),
          new NetNamedPipeBinding(),
          "PipeReverse");

        host.Open();

        Console.WriteLine("Service is available. " +
          "Press <ENTER> to exit.");
        Console.ReadLine();

        host.Close();
      }
    }
  }

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

В этом руководстве сервер просто отвечает клиенту методом обратного вызова, вместо этого я храню ссылку на клиента в списке подписчиков. Когда мне нужно отправить данные обратно клиентам, мне нужна ссылка на объект Service, чтобы я мог использовать функцию обратного вызова.

Есть ли способ публикации Сервиса с использованием WCF, который позволяет вам иметь ссылку на объект сервиса? или я могу получить ссылку на объект службы из объекта host ?

Буду признателен за любую помощь ...

Ответы [ 3 ]

2 голосов
/ 25 февраля 2009

Вы можете использовать шаблон синглтона в вашем классе StringReverser и передать его экземпляр конструктору ServiceHost:

ServiceHost host = new ServiceHost(
  StringReverser.Instance,
  new Uri[]{new Uri("net.pipe://localhost")}
);
2 голосов
/ 19 августа 2014

Я согласен, что ответ Жюльена - правильный подход, но он неполный (по крайней мере, для .NET 4.5) После передачи экземпляра службы необходимо установить режим контекста экземпляра для ServiceHost в значение Single. Если вы этого не сделаете, вы получите ошибку при вызове метода ServiceHost Open().

Способ установки режима контекста был совсем не очевиден. Вот фрагмент одной из моих программ, взятый из другого ответа SO:

var baseAddress = new Uri("http://localhost:15003/MockGateway");

using (var host = new ServiceHost(new MockGatewayService(), baseAddress))
{
    // Since we are passing an instance of the service into ServiceHost (rather 
    // than passing in the type) we have to set the context mode to single.
    var behavior = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
    behavior.InstanceContextMode = InstanceContextMode.Single;

    // Continue to use the service here.  If you ever need to get a reference
    // to the service object you can do so with...
    MockGatewayService myService = host.SingletonInstance as MockGatewayService;

    // ...
}
0 голосов
/ 25 февраля 2009

в вашем сервисном договоре вы можете позвонить

OperationContext.Current.GetCallbackChannel ());

в любом методе, который вызывается после подключения службы, а затем передает его из контракта на обслуживание. Обычно у меня есть метод соединения, где я получаю руководство для клиента и получаю обратный вызов там. Это сложнее, чем кажется. Вам нужна либо одиночная / глобальная переменная, чтобы вывести ее (легко), либо вам нужно сделать так, чтобы WCF мог использовать параметризованные конструкторы (трудно). Для последнего, более правильного способа сделать это вам нужно свернуть свои собственные классы, которые реализуют IInstanceProvider и IEndPointBehavior, и добавить свое поведение к интересующей вас конечной точке. Это дает дополнительное преимущество, позволяя вам использовать разные конструкторы с разными конечными точками без переопределения вашего контракта. К сожалению, нет безопасных способов сделать это, так как вам придется использовать рефлексию. Извините, я не могу предоставить образец, но все, что у меня есть, является собственностью.

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