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% 清楚你想要做什么,但如果你只是希望能够在同一个地址上托管不同的合约,并在一个服务类中实现,这是完全可能的。要共享端点地址,您必须确保为每个服务端点使用相同的绑定实例。

这是一个完整的示例,它定义了 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();
    }
}
于 2009-09-17T08:36:57.277 回答
1

我怀疑这会奏效。Xml 序列化可能是这里最大的问题。

另外,我认为您实际上并不需要它。如果我处于你的位置,我会尝试抽象我与服务的通信。基本上,您总是会向服务发送“消息”,该服务的“目标”是您想要访问的类之一。该服务将始终以“响应”进行回复,其内容将由“消息”发送到的类填充。

另一种方法是通过一个服务将所有这些消息路由,该服务会将请求回显到适当的服务。这样可以保持可扩展性,但它仍然有很大的配置负担。

HTH。

于 2009-09-17T08:28:57.837 回答
0

听起来您想保留单独的服务,但有某种路线通过的公共汽车。MSMQ 也许,然后您可以拥有一个服务,它将每条消息都弹出到特定队列中,然后专用服务可以从该特定队列中读取该消息。

诚然,这并不是真正的基于 WCF 的解决方案。

由多个类实现的单个接口(读作 ServiceContract)的概念是行不通的。所以你需要一个“怪物”服务来实现所有并路由到正确的服务。立面图案浮现在脑海中。

于 2009-12-01T13:46:00.750 回答