2009-09-17 4 views
6

Мы используем WCF для связи между клиентом и серверным приложением. Клиентское приложение имеет множество функций, требующих связи с сервером, и мы решили реализовать это в нескольких классах (разделение ответственности).Служба WCF возвращает другую услугу (сервисная фабрика?)

На данный момент мы создаем новые конечные точки WCF и контракты на обслуживание для каждого объекта - выставление счетов , Учет, управление контентом и т. Д. Это вызывает большую конфигурацию конечных точек как на клиенте, так и на сервере (с потенциальными проблемами неправильной конфигурации при переходе на тестовые и производственные платформы).

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

например.

using (IServiceClientFactory serviceClientFactory = new RealProxyServiceClientFactory()) 
      { 
       // This is normal WCF proxy object creation. 
       IServiceFactory serviceFactory = serviceClientFactory.CreateInstance<IServiceFactory>(""); 

       // This is what we would like to do 
       IInvoiceService invoiceService = serviceFactory.getService(typeof(IInvoiceService)); 

       invoiceService.executeOperation(data); 
      } 

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

Возможно ли это?

ответ

1

Сомневаюсь, что это сработает. Сериализация Xml может быть самой большой проблемой здесь.

Также я не думаю, что вам это действительно нужно. Если бы я был на вашем месте, я бы попытался отвлечь свое общение с сервисом. В основном вы всегда отправляете «сообщение» службе, у которой «Target» является одним из классов, к которым вы хотели получить доступ. Служба всегда ответит «Ответ», содержимое которой будет заполнено классом, на который было отправлено сообщение «Сообщение».

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

HTH.

+0

Благодарим за ответ.Сериализация службы не является решением, методы обслуживания должны обрабатываться на сервере. Параметры должны быть Serializable, но сам метод должен выполняться на сервере. Я нашел документ об ServiceContracts с SessionMode, который я сейчас тестирую. – Thies

+0

Я никогда не предлагал сериализацию службы. Сегментация Xml делает работу WCF. Он отвечает за перенос ваших объектов и перевод их в Xml и наоборот. Весь смысл моего ответа заключается в том, чтобы объяснить вам, что упаковка ваших запросов и ответов на обслуживание может быть решением вашей проблемы. –

3

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

Вот полный пример, который определяет 3 контракта, 1 класс обслуживания, который реализует все из них, и ServiceHost с 3 контракта конечными точками на точно такой же адрес:

using System; 
using System.ServiceModel; 

[ServiceContract] 
interface IContractA 
{ 
    [OperationContract] 
    void A(); 
} 

[ServiceContract] 
interface IContractB 
{ 
    [OperationContract] 
    void B(); 
} 

[ServiceContract] 
interface IContractC 
{ 
    [OperationContract] 
    void C(); 
} 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
class Service : IContractA, IContractB, IContractC 
{ 
    public Service() 
    { 
    } 

    public void A() 
    { 
     Console.WriteLine("A"); 
    } 

    public void B() 
    { 
     Console.WriteLine("B"); 
    } 

    public void C() 
    { 
     Console.WriteLine("C"); 
    } 
} 

class Program 
{ 
    public static void Main(string[] args) 
    { 
     Uri address = new Uri("net.pipe://localhost/Service/"); 
     ServiceHost host = new ServiceHost(new Service(), address); 
     NetNamedPipeBinding binding = new NetNamedPipeBinding(); 
     host.AddServiceEndpoint(typeof(IContractA), binding, string.Empty); 
     host.AddServiceEndpoint(typeof(IContractB), binding, string.Empty); 
     host.AddServiceEndpoint(typeof(IContractC), binding, string.Empty); 
     host.Open(); 

     IContractA proxyA = ChannelFactory<IContractA>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(address)); 
     proxyA.A(); 
     ((IClientChannel)proxyA).Close(); 

     IContractB proxyB = ChannelFactory<IContractB>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(address)); 
     proxyB.B(); 
     ((IClientChannel)proxyB).Close(); 

     IContractC proxyC = ChannelFactory<IContractC>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(address)); 
     proxyC.C(); 
     ((IClientChannel)proxyC).Close(); 

     host.Close(); 
    } 
} 
+0

Спасибо, бобби, не всегда легко определить проблему, пока не узнаете решение;). Как вы заявляете; Я заинтересован в размещении многих контрактов на одном адресе, но желательно иметь реализацию сервиса в разных классах. Используя ваше предложение, у меня будет один класс «монстр», который реализует все службы, проксируя вызовы на правильные услуги, отличные от WCF, - чего я бы хотел избежать. – Thies

+0

Звучит сложно достичь всего, что вы хотите. Если вы хотите, чтобы у клиентов был хороший типизированный контракт, но вы фактически не хотите, чтобы ваш класс обслуживания реализовал все из них, вы могли бы запихнуть много странного общего кода обработки сообщений и переопределить поведение метаданных WCF, чтобы надлежащее WSDL все еще может быть сгенерирован. – bobbymcr

0

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

На самом деле это не решение на основе WCF.

Понятие одного интерфейса (прочитанного как ServiceContract), реализованное несколькими классами, не будет работать. Таким образом, вам понадобится один «монстр», который реализует все и направляет к правильному сервису. Фасад рисунка напоминает.

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