在多个绑定上托管WCF服务的选定方法

时间:2018-07-08 11:13:57

标签: c# wcf

面试中有人问我这个问题,但我不知道答案。

问题是我们在一项服务中有5个运营合同。我们希望将它们全部托管在一个绑定中,比如说http,而其中只有两个托管在另一个绑定中。因此,这两种方法都必须托管在绑定上,并且必须没有任何重复。

我们如何做到这一点?甚至有可能吗?

1 个答案:

答案 0 :(得分:0)

是的,有可能。我们可以按如下所示构造接口协定,以分离出我们只希望在一个端点上可用的方法:

[ServiceContract]
interface ILimitedAvailabilityOp
{
    [OperationContract]
    string OpB();
}

[ServiceContract]
interface IAllOfMyOps : ILimitedAvailabilityOp
{
    [OperationContract]
    string OpA();
}

因此,总共有两种方法可以通过继承在IAllOfMyOps上使用,而ILimitedAvailabilityOp的操作只对一个绑定可用。对于我们的服务实施,我们执行以下所有操作:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class MyService : IAllOfMyOps
{
    public string OpA()
    {
        return "A";
    }

    public string OpB()
    {
        return "B";
    }
}

创建服务实例时,我们可以对具有两个不同绑定的两个不同端点执行以下操作。在网络tcp端点上,我们使操作A和B都可用,在仅绑定B的命名管道上。

static void CreateService()
{
    var myService = new MyService();
    var serviceHost = new ServiceHost(myService);
    serviceHost.AddServiceEndpoint(typeof(IAllOfMyOps), new NetTcpBinding(), "net.tcp://localhost:61234/MyService/IAllOfMyOps");
    serviceHost.AddServiceEndpoint(typeof(ILimitedAvailabilityOp), new NetNamedPipeBinding(), "net.pipe://localhost/MyService/ILimitedAvailabilityOp");
    serviceHost.Open();
}

要连接的客户端如下所示:

class MyClient : ClientBase<IAllOfMyOps>, IAllOfMyOps
{
    public MyClient(Binding binding, EndpointAddress endpoint) : base(binding, endpoint) { }

    public string OpA()
    {
        return base.Channel.OpA();
    }

    public string OpB()
    {
        return base.Channel.OpB();
    }
}

我们将像这样连接到它:

static void Connect()
{
    var tcpClient = new MyClient(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:61234/MyService/IAllOfMyOps"));
    Console.WriteLine(tcpClient.OpA());
    Console.WriteLine(tcpClient.OpB());
    tcpClient.Close();

    var namedPipeClient = new MyClient(new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/MyService/ILimitedAvailabilityOp"));
    Console.WriteLine(namedPipeClient.OpB());
    Console.WriteLine(namedPipeClient.OpA()); // this would fail
    namedPipeClient.Close();
}

因此,我们在任何地方都没有重复任何代码,并且在一个绑定上有两个操作可用,而在另一个绑定上只有一个可用。