WCF :: ServiceHost & AddServiceEndpoint: типы аргументов меняются местами? - PullRequest
1 голос
/ 01 июня 2009

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

Почему компонент 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 должен быть тем, кто принимает интерфейс?

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

Ответы [ 3 ]

2 голосов
/ 01 июня 2009

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

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

2 голосов
/ 01 июня 2009

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

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

Конечная точка поддерживает определенную реализацию, как вы говорите: какую бы вы ни использовали при создании ServiceHost. Целью конечных точек является не предоставление нескольких реализаций, а предоставление нескольких протоколов / привязок для доступа к одной реализации.

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

1 голос
/ 01 июня 2009

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

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

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

...