简体   繁体   中英

Hosting selected methods of a wcf service on multiple binding

I have been asked this question on an interview and i dont know the answer yet.

Question is we have 5 operation contracts in a service. We want to host all of them of one binding, lets say http and only two of them on another binding too. So those two methods must be hosted on both the bindings and Without any duplication.

How do we do this? Is it even possible?

Yes, it's possible. We can structure the interface contract as follows to separate out the methods we want available on only one endpoint:

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

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

So in total we have two methods which are both available on IAllOfMyOps via inheritance, and ILimitedAvailabilityOp has the operation we will make available on only one binding. For our service implementation, we implement all the operations as below:

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

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

When we create the service instance, we can do as follows with two different endpoints having two different bindings. On the net tcp endpoint, we make both ops A and B available, on the named pipe binding just 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();
}

The client to connect would look like this:

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

And we'd connect to it like this:

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

Thus we haven't repeated any code anywhere, and we have two ops available on one binding, and only one available on another.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM