2012-05-17 2 views
3

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

узел службы:

protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
{ 
    ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses); 

    if (host.Description.Endpoints.Count == 0) 
    { 
      host.AddDefaultEndpoints(); 
    } 

    host.Description.Behaviors.Add(new MessagingErrorHandler());  

    return host; 
} 

Так что я попытался это добавить пользовательские привязки к моей конечной точке, но зарегистрировать конечную точку, с привязкой, похоже, я должен использовать AddServiceEndpoint, но это потребует интерфейс, который неизвестен. Я знаю, что могу получить все интерфейсы, которые реализует serviceType, и делать getInterfaces()[0], но это, кажется, небезопасный подход ко мне. Итак, есть способ зарегистрировать мою конечную точку с пользовательской привязкой и не знать интерфейс, или, может быть, лучший подход, который я должен принять.

Моя попытка добавления пользовательских привязки:

CustomBinding compression = new CustomBinding(); 
compression.Elements.Add(new GZipMessageEncodingBindingElement()); 
foreach (var uri in baseAddresses) 
{ 
    host.AddServiceEndpoint(serviceType, compression, uri);//service type is not the interface and is causing the issue 
} 
+0

Можете ли вы пояснить, почему интерфейс неизвестно? Возможно, я я не понял, но кажется, что вы либо определяете конечную точку службы (так что должен иметь интерфейс), либо нет - поэтому не нужно связывать. – Basic

+0

serviceType может иметь несколько интерфейсов, поэтому я не знаю, какой из этих интерфейсов для назначения конечной точке –

+0

Гораздо яснее, спасибо – Basic

ответ

2

Ваш заказ связывания необходим транспорт элемент привязки; в настоящее время у вас есть только элемент привязки кодировки сообщения. Вам нужно добавить, вероятно, HttpTransportBindingElement к пользовательскому связывания, а также:

CustomBinding compression = new CustomBinding(
    new GZipMessageEncodingBindingElement() 
    new HttpTransportBindingElement()); 

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

private Type GetContractType(Type serviceType) 
    { 
     if (HasServiceContract(serviceType)) 
     { 
      return serviceType; 
     } 

     Type[] possibleContractTypes = serviceType.GetInterfaces() 
      .Where(i => HasServiceContract(i)) 
      .ToArray(); 

     switch (possibleContractTypes.Length) 
     { 
      case 0: 
       throw new InvalidOperationException("Service type " + serviceType.FullName + " does not implement any interface decorated with the ServiceContractAttribute."); 
      case 1: 
       return possibleContractTypes[0]; 
      default: 
       throw new InvalidOperationException("Service type " + serviceType.FullName + " implements multiple interfaces decorated with the ServiceContractAttribute, not supported by this factory."); 
     } 
    } 

    private static bool HasServiceContract(Type type) 
    { 
     return Attribute.IsDefined(type, typeof(ServiceContractAttribute), false); 
    } 
+0

Спасибо, это очень помогло. –

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