ВКФ::ServiceHost и AddServiceEndpoint:Типы аргументов поменялись местами?

StackOverflow https://stackoverflow.com/questions/933570

  •  06-09-2019
  •  | 
  •  

Вопрос

Пока я пытался изучить WCF, и это казалось достаточно простым, я столкнулся со странной ситуацией... по крайней мере, мне она кажется странной.

Почему ctor ServiceHost принимает конкретный класс, а AddServiceEndpoint — интерфейс, а не наоборот?кажется, последнее более логично с точки зрения ООП.

Учтите следующее:

    [ServiceContract]
    interface IVocalAnimal
    {
        [OperationContract]
        string MakeSound();
    }
  ...      
  public class Dog : IVocalAnimal
  {
     public string MakeSound()
     {
        return("Woof!");
     }
  }
 ...
 public class Cat : IVocalAnimal
  {
     public string MakeSound()
     {
        return("Meeooow!");
     }
  }

Итак, теперь мы хотим создать службу AnimalSound, к которой вы можете подключиться, чтобы получить звук собаки или кошки через /AnimalSoundService/Dog или /AnimalSoundService/Cat.

...
Uri baseAddress = new Uri("net.pipe://localhost/AnimalSoundService");
ServiceHost serviceHost = new ServiceHost(typeof(IVocalAnimal), baseAddress);
serviceHost.AddServiceEndpoint(typeof(Dog), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "Dog");
serviceHost.AddServiceEndpoint(typeof(Cat), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "Cat");
...

Но приведенный выше код не скомпилируется, поскольку по какой-то причине, которую я не совсем понимаю, ctor ServiceHost хочет конкретный класс (поэтому либо Dog, либо Cat), а EndPoint хочет интерфейс.

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

Кстати, я не педантик... Я просто честно пытаюсь понять, поскольку уверен, что это я что-то упустил.

Это было полезно?

Решение

Когда вы создаете ServiceHost, вы создаете реальную службу, поэтому она должна быть конкретной.

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

Конечная точка ДЕЙСТВИТЕЛЬНО поддерживает конкретную реализацию, как вы говорите:какой бы из них вы ни использовали при создании ServiceHost.Целью конечных точек является не предоставление нескольких реализаций, а предоставление нескольких протоколов/привязок для доступа к одной реализации.

Если вам нужны отдельные службы Dog и Cat, я считаю, что вам понадобятся два ServiceHost, каждый с одной конечной точкой NetNamedPipeBinding.

Другие советы

Я вижу, о чем ты думаешь.С точки зрения ООП это имеет смысл, но это не точка зрения сервиса.Услуга — это группа операций.Эта группа операций определяется в контракте.Вы можете использовать классы для моделирования контрактов служб, но большинство из них используют интерфейсы, поскольку интерфейсы представляют собой более прямую модель.В MSDN есть очень хорошая дискуссия этих концепций.

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

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

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

Например, у вас может быть служба, которая предоставляет односторонний контракт через MSMQ и двусторонний контракт через HTTP.Или, возможно, он предоставляет контракт JSON для одного URL-адреса и XML для другого.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top