WCF — ищу наилучшую практику при наличии нескольких контрактов, совместно использующих общие методы

#c# #wcf

#c# #wcf

Вопрос:

Я намерен создать один базовый модуль, предоставляющий интерфейсы, с которыми будут взаимодействовать другие большие модули (разные клиенты). Если, скажем, существует группа методов:

 void Method_A();
void Method_B();
void Method_X1();
  

предоставлять доступ к одному типу клиентов (модуль «X1») и:

 void Method_A();
void Method_B();
void Method_X2();
  

предоставлять доступ к клиентам другого типа (модуль «X2») и знать, что Method_A и Method_B должны иметь точную реализацию … тогда как я могу наилучшим образом спроектировать архитектуру сервисов (с точки зрения сервисов и контрактов)?

Есть ли какой-либо шанс реализовать Method_A и method_B только один раз (а не 2 раза в разных реализациях контракта)?

Как я могу воспользоваться преимуществами наследования интерфейса при использовании WCF?

Заранее благодарю вас всех и, пожалуйста, дайте мне знать, если мне нужно сделать это более понятным!

@marc_s… Я был бы действительно признателен за вашу точку зрения…

Ответ №1:

Классы могут наследовать методы, удовлетворяющие интерфейсу, поэтому у вас мог бы быть IServiceBase интерфейс и ServiceBase класс, который просто реализует Method_A и Method_B , затем выделять уникальные методы в отдельные интерфейсы, наконец, объединяя их вместе в классы, которые наследуют ServiceBase и реализуют либо Interface1, либо Interface2. например:

 [ServiceContract]
public interface IServiceBase
{
    [OperationContract]
    void Method_A();

    [OperationContract]
    void Method_B();
}

[ServiceContract]
public interface IService1 : IServiceBase
{
    [OperationContract]
    void Method_X1();
}

[ServiceContract]
public interface IService2 : IServiceBase
{
    [OperationContract]
    void Method_X2();
}

public abstract class ServiceBase : IServiceBase
{
    void Method_A()
    {
        ... implementation here ...
    }

    void Method_B()
    {
        ... implementation here ...
    }
}

public class Service1 : ServiceBase, IService1
{
    void Method_X1()
    {
        ... implementation here ...
    }
}

public class Service2 : ServiceBase, IService2
{
    void Method_X2()
    {
        ... implementation here ...
    }
}
  

Комментарии:

1. Это выглядит действительно хорошо… Спасибо… Я попробую и вернусь к вам

2. Честно говоря, для данного сценария ваше решение хорошее. Я просто пытаюсь выяснить, какое решение является лучшим и гибким при переходе к приложениям реального мира… Как бы вы сравнили свое решение с решением marc? Какие бы мысли у вас ни были на уме… изложите их в письменном виде, спасибо!

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

Ответ №2:

Меня вызвали !?!?! 🙂

Если у вас один интерфейс

 public interface IServiceA
{
  void Method_A();
  void Method_B();
  void Method_X1();
}
  

и второй

 public interface IServiceB
{
  void Method_A();
  void Method_B();
  void Method_X2();
}
  

вы можете абсолютно совместно использовать код реализации для двух общих методов на стороне сервера.

Вы бы создали два класса MethodAHandler и MethodBHandler на своем сервере в общей библиотеке классов (или в двух отдельных общих сборках), а затем вы могли бы использовать что-то вроде:

 using MethodHandlers;  // contains the two method handlers

public class ServiceA : IServiceA
{
   public void Method_A()
   {
       MethodAHandler hnd = new MethodAHandler();
       hnd.HandleMethodCall();
   }

   public void Method_B()
   {
       MethodBHandler hnd = new MethodBHandler();
       hnd.HandleMethodCall();
   }

   public void Method_X1()
   {
       // handle method X1 call here or delegate to another handler class
   }
}
  

и для второго сервиса:

 using MethodHandlers;  // contains the two method handlers

public class ServiceB : IServiceB
{
   public void Method_A()
   {
       MethodAHandler hnd = new MethodAHandler();
       hnd.HandleMethodCall();
   }

   public void Method_B()
   {
       MethodBHandler hnd = new MethodBHandler();
       hnd.HandleMethodCall();
   }

   public void Method_X2()
   {
       // handle method X2 call here or delegate to another handler class
   }
}
  

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

Комментарии:

1. Привет, Марк. Очень хороший и полный ответ… Я действительно уважаю вас! Я нахожу ваш ответ гораздо более гибким (в случае, если даже методы ‘A’ и ‘B’ больше не будут распространенными). Как бы вы прокомментировали «C. Лоуренс Уэнхэм «подход с использованием абстрактного класса? Плюсы и минусы? … Спасибо!

2. Почему-то мне нравится эта идея наследования… Вы предпочитаете не использовать наследование? Что вы думаете?