6

クライアントとサーバー アプリケーション間の通信に 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);
            }

手がかりは、利用可能にしたいサービス連絡先ごとのエンドポイント構成ではなく、クライアント/サーバーのペアごとの単一のエンドポイント構成です。

これは可能ですか?

4

3 に答える 3

3

私はあなたが何をしようとしているのか100%明確ではありませんが、1つのサービスクラス内の実装で同じアドレスで異なるコントラクトをホストできるようにしたいだけなら、これは完全に可能です。エンドポイントアドレスを共有するには、各サービスエンドポイントに同じバインディングインスタンスを使用していることを確認する必要があります。

これは、3つのコントラクト、それらすべてを実装する1つのサービスクラス、およびまったく同じアドレスに3つのコントラクトエンドポイントを持つServiceHostを定義する完全なサンプルです。

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();
    }
}
于 2009-09-17T08:36:57.277 に答える
0

個別のサービスを維持したいが、ルートが通過するある種のバスが必要なようです。MSMQ の場合は、すべてのメッセージを特定のキューにポップする 1 つのサービスを用意し、専用のサービスがその特定のキューからそれを読み取ることができます。

確かに、実際にはWCFベースのソリューションではありません。

複数のクラスによって実装された単一のインターフェース (ServiceContract として読み取られる) の概念は機能しません。したがって、すべてを実装し、正しいサービスにルーティングする 1 つの「モンスター」サービスが必要になります。ファサードのパターンが思い浮かびます。

于 2009-12-01T13:46:00.750 に答える