3

Microsoft による圧縮のサンプルに従います。エンコーダー、エンコーダー ファクトリ、バインディング要素をソリューションに追加しました。サンプルとの違いは、構成ファイル (要件) を介してエンドポイントを登録せず、代わりにカスタムの Service Host Factory を使用することです。

サービス ホスト:

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
}
4

1 に答える 1

3

カスタム バインディングにはトランスポート バインディング要素が必要です。現在、メッセージ エンコーディング バインディング要素しかありません。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); 
    }
于 2012-05-17T21:57:24.393 に答える