2013-09-06 5 views
0

У меня есть два проекта, один из которых - набор служб WCF (давайте позвоним P1), а другой - стандартное веб-приложение (P2).WCF-услуги, потребляющие

В начале мы использовали сервисы P1 в P2 как службы SOAP, и все прошло хорошо. Позже мы заметили, что во всех наших проектах мы размещаем как P1 & P2 на том же сервере. Поэтому мы подумали, почему мы должны хранить это так: это означает: почему мы должны последовательно сериализовать/дезацинировать запрос/ответ каждый раз для каждого метода, когда он работает на одном сервере. Поэтому мы приняли решение использовать P1 в качестве стандартной ссылки на библиотеку проектов в P2.

Мы должны были внести много изменений, потому что имя класса прокси изменяется и необходимо удалить метод закрытия клиента после каждого вызова. Теперь у нас есть новое развертывание, которое потребует, чтобы P1 находился на другом сервере, чем P2, который мы можем изменить, и нам нужно снова использовать P1 как услугу WCF - это означает множество изменений по всему P2 и заканчивается сериализацией накладные расходы на все другие развертывания!

Вопрос в том, есть ли способ сделать такую ​​динамическую ссылку на P1, поэтому кодирование не требуется независимо от того, развертывание находится на 1 или 2 серверах?

ответ

2

Возможно, что служба WCF запускается локально (ссылка на проект) или как услуга, основанная на некотором ключе в web.config. Я сделал следующий пример, но я не проверить это, но я сделал именно подобную вещь, прежде чем

Добавить ключ в веб-конфигурации говорят serviceMode = «локальный/услугу»

Тогда у вас есть интерфейс службы WCF

[ServiceContract] 
    public class ICalculator 
    { 
     [OperationContract] 
     int Add(int x, int y); 
    } 

реализация

public class Calculator 
    { 
     public int Add(int x, y) 
     { 
     return x+y; 
     } 
} 

/// Теперь в вашем веб-приложения

вы будете иметь

public LocalProxy:ICalculator //this will use direct instance of the Calculator Service 
    { 
     private ICalculator _calculator 

     public LocalProxy(ICalculator calculator) 
     { 
     _calculator =calculator; 
     } 

     public int Add(int x, int y) 
     { 
     return _calculator.Add(x,y); 
     } 

} 




public class RemoteProxy:ICalculator ///This will be real wcf proxy 

    { 


     public int Add (int x,int y) 
     { 

      var endpointAddress = new EndpointAddress(EndpointUrl); 
      ChannelFactory<ICalculator> factory = null; 
      ICalculator calculator ; 

      try 
      { 
      // Just picking a simple binding here to focus on other aspects 
      Binding binding = new BasicHttpBinding(); 

      factory = new ChannelFactory<ICalculator>(binding); 
      calculator= factory.CreateChannel(endpointAddress); 
      if (calculator== null) 
      { 
       throw new CommunicationException(
        String.Format("Unable to connect to service at {0}", endpointUrl)); 
      } 

      int sum= calculator.Add(x,y); 
      ((IClientChannel)calculator).Close(); 

      calculator = null; 
      factory.Close(); 
      factory = null; 

      return sum; 
      } 
      finally 
      { 
      if (calculator!= null) ((IClientChannel)calculator).Close(); 
      if (factory != null) factory.Abort(); 
      } 
     } 

    } 

Теперь, как вы используете его

ICalculator _calculatorProxy; 

    //get the web config key here, you may use strategy pattern to select between the two proxies 


    if(key=="local) 
    { 
    _calculator= new LocalProxy(new Calculator) 
    } 
    else 
    { 
    _calculator= new RemoteProxy(); 
    } 


    //then 
    _calculator.Add(3,5); 

Примечание: Определите интерфейсы и контракты данных в отдельной сборке, так что вы можете поделиться им с веб-приложением, которое нуждается в ФОС перспективе как услугу.

1

Все ваши компоненты в P2, которые потребляют услуги от P1, должны потреблять только служебный интерфейс (то есть IMyService, ISomeOtherService). Им не важно, является ли это локальным экземпляром или прокси-сервером, и они не должны закрывать соединение.

Самый простой (imho), чтобы реализовать это, используя инъекцию зависимости через IoC, например Castle Windsor (это единственный, с которым я смутно знаком, но есть несколько других). Контейнер будет отвечать за предоставление экземпляров интерфейсов службы. Вы можете предоставить различные реализации и настроить контейнер во время выполнения с соответствующим (служба WCF или локальный экземпляр). Контейнер также будет нести ответственность за утилизацию компонентов обслуживания, как только они больше не требуются (т. Е. Вызывая Close() на прокси WCF и ничего не делая для других).

Это большая тема, поэтому я предлагаю вам искать в Интернете некоторые ключевые слова - там много материала.

Смежные вопросы