WCF服务返回另一个服务(服务工厂?)

时间:2009-09-17 08:14:09

标签: c# .net wcf endpoints

我们正在使用WCF进行客户端和服务器应用程序之间的通信。客户端应用程序具有许多需要与服务器通信的功能 - 我们选择在多个类中实现此功能(分离责任)

当时,我们正在为每个对象创建新的WCF端点和服务合同 - 开票,会计,内容管理等。这会导致客户端和服务器上的大量端点配置(进入时可能存在错误配置问题)测试和生产平台)。

我想知道我是否可以定义一个可以提供多个服务联系实现的WCF端点。然后,我们的配置文件将包含一个端点(到服务工厂),我可以通过指定我感兴趣的服务的接口来请求不同的服务。

e.g。

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);
            }

线索是每个客户端/服务器对的单个端点配置,而不是我希望提供的每个服务联系人的端点配置。

这可能吗?

3 个答案:

答案 0 :(得分:3)

我不是100%清楚你要做什么,但如果你只是想在一个服务类内部实现同一地址上的不同合同,这是完全可能的。要共享端点地址,必须确保为每个服务端点使用相同的绑定实例。

这是一个完整的示例,它定义了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();
    }
}

答案 1 :(得分:1)

我怀疑这会起作用。 Xml序列化可能是这里最大的问题。

此外,我认为你并不需要它。如果我在你的鞋子里,我会尝试和我的服务沟通。基本上,您总是会向服务发送“消息”,其中“目标”是您要访问的类之一。该服务将始终以“响应”回复,其中的内容将由发送“消息”的类填充。

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

HTH。

答案 2 :(得分:0)

听起来你想保留你的单独服务,但有一些路线是通过的公共汽车。 MSMQ可能,然后你可以有一个服务,将每条消息弹出到一个特定的队列,然后专用服务可以读取该特定队列。

虽然确实不是基于WCF的解决方案。

由多个类实现的单个接口(读作ServiceContract)的概念不起作用。所以你需要一个“怪物”服务来实现所有并通过正确的服务路由。门面图案让人想起。