1

簡略化された構成 (つまり、構成<service>ファイルに明示的なノードがない) を使用して、IIS 経由で公開された同じクラスによって実装されているサービス コントラクトがかなりあります。

これは正常に機能し、同じ URL を指すエンドポイントを自動的に構築するロジックがクライアントにあるため、多くの問題を回避できます。

ここで、クライアントとサーバーの両方でコントラクトの 1 つをカスタマイズしたいと思います。これは、動作が他のコントラクトとはかなり異なるためです。この特殊なコントラクト クラスにはストリーミング トランスポートを使用したいと考えています。これは、Streamインスタンスを返し、取得するためです。

<service>共有実装クラスを指し、この特別な契約インターフェイスを使用してサーバーにノードを追加しようとするとすぐに、他のサービスの自動構成全体が失われ、1 つのサービスが公開されたままになります。これは、単一の実装クラスを使用しているという事実に関係していると思います。Wcf は、構成にそのクラス名のサービスがあることを検出するとすぐに、他のコントラクトのエンドポイントの自動生成を停止します。

同じクラスを共有し、簡素化された構成を維持しながら、これを機能させる方法はありますか?

4

1 に答える 1

1

これを行うには、独自のサービス ファクトリを作成し、アクティブ化プロセスの一部をオーバーライドします。

このような 2 つのサービス契約があるとします。

public interface IService1
{
    [OperationContract]
    string GetData(int value);
}

[ServiceContract]
public interface IService2
{
    [OperationContract]
    string Foobar();
}

これらがこのような単一のクラスで実装されていると仮定します。

public class Service1 : IService1, IService2
{
    public string GetData(int value)
    {
        return string.Format("You entered: {0}", value);
    }
    public string Foobar()
    {
        return "foobar";
    }
}

ここで、2 番目のサービス コントラクトだけのエンドポイントを変更する場合は、.svc ファイルに Factory プロパティを追加して、カスタム サービス ファクトリの実装をポイントします。

<%@ ServiceHost Language="C#" Debug="true" Factory="SimpleWCF2.MyServiceFactory" Service="SimpleWCF2.Service1" CodeBehind="Service1.svc.cs" %>

次に、カスタム サービス ホストをインスタンス化するカスタム サービス ファクトリを作成します。カスタム サービス ホストで、ApplyConfiguration をオーバーライドし、コントラクト 2 の既定のエンドポイントを削除して、カスタム エンドポイント構成に置き換えます。たとえば、ここでは、デフォルトの「basicHttpBinding」をコントラクト 2 のみの「WsHttpBinding」に置き換えています。もちろん、必要に応じてバインディングを構成できます (ストリーミングについて言及しました)。これは単なる例です。

public class MyServiceFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        return new MyServiceHost(serviceType, baseAddresses);
    }
}

public class MyServiceHost : ServiceHost
{
    public MyServiceHost(Type serviceType, params Uri[] baseAddresses) :
        base (serviceType, baseAddresses)
    { }

    protected override void ApplyConfiguration()
    {
        base.ApplyConfiguration();

        AddDefaultEndpoints();

        // Remove the default endpoint for IService2
        var defaultEp = this.Description.Endpoints.FirstOrDefault(e => e.Contract.ContractType == typeof(IService2));
        this.Description.Endpoints.Remove(defaultEp);

        // Add a new custom endpoint for IService2
        this.AddServiceEndpoint(typeof(IService2), new WSHttpBinding(), "test");
    }
}

それでおしまい。簡素化された構成を変更する必要はありません。

これで、クライアントは新しいサービス エンドポイントを介して 2 番目のコントラクトを検出します。たとえば、サンプルの WCF テスト クライアントを次に示します。

ここに画像の説明を入力

于 2013-11-01T03:02:43.010 に答える