0% found this document useful (0 votes)
75 views8 pages

System System - Servicemodel: Using Using Namespace

This document discusses Windows Communication Foundation (WCF) and how to create a simple WCF service that exposes a function to reverse strings. It demonstrates building a WCF server that implements the string reversing function and hosts two endpoints - HTTP and named pipes. It then shows creating a WCF client that connects to the server over both endpoints and calls the reversing function by creating proxies. The document explains how little code is needed to create the basic service and client using WCF.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
75 views8 pages

System System - Servicemodel: Using Using Namespace

This document discusses Windows Communication Foundation (WCF) and how to create a simple WCF service that exposes a function to reverse strings. It demonstrates building a WCF server that implements the string reversing function and hosts two endpoints - HTTP and named pipes. It then shows creating a WCF client that connects to the server over both endpoints and calls the reversing function by creating proxies. The document explains how little code is needed to create the basic service and client using WCF.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 8

WCF:

At its core, WCF is a mechanism that facilitates communication between processes - either on the same machine or
separate machines.

What we're building today will look a lot like a simple remote procedure call. We'll be building a server that exposes a
function that can be called by a client. Just to show how easy it is to change the transport layer, the client will connect
to the server through two different mechanisms - http and named pipe.

The first thing we need to do is define what the client will have access to. We do this by defining an interface in C#
and giving it a few attributes for WCF. The server will create a class that implements the interface to actually do the
work. The client will just be provided the interface so it knows which functions are available.

Starting with the server, the first thing we need to do is create a class that implements this interface and provides the
functionality behind ReverseString. Believe or not, that's it for a fully functional WCF server. Below is all of the
code put together.

using System;
using System.ServiceModel;

namespace WCFServer
{
  [ServiceContract]
  public interface IStringReverser
  {
    [OperationContract]
    string ReverseString(string value);
  }

  public class StringReverser : IStringReverser


  {
    public string ReverseString(string value)
    {
      char[] retVal = value.ToCharArray();
      int idx = 0;
      for (int i = value.Length - 1; i >= 0; i--)
        retVal[idx++] = value[i];

      return new string(retVal);


    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      using (ServiceHost host = new ServiceHost(
        typeof(StringReverser),
        new Uri[]{
          new Uri("http://localhost:8000"),
          new Uri("net.pipe://localhost")
        }))
      {
        host.AddServiceEndpoint(typeof(IStringReverser),
          new BasicHttpBinding(),
          "Reverse");

        host.AddServiceEndpoint(typeof(IStringReverser),
          new NetNamedPipeBinding(),
          "PipeReverse");

        host.Open();

        Console.WriteLine("Service is available. " +  


          "Press <ENTER> to exit.");
        Console.ReadLine();

        host.Close();
      }
    }
  }
}

Here's my simple interface. It provides a function that takes a string and returns a new string with all of the characters
reversed. The ServiceContract attribute tells WCF that this interface can be exposed for client use. The
OperationContract attributes tells WCF that ReverseString is part of this service contract and can be used by
clients. There are lots of optional settings that can be applied to both of these attributes, but this is all that's required
to get things up and running. The System.ServiceModel namespace is available by adding a reference to the
System.ServiceModel assembly to your project, which is available in the default installation of .NET 3.5

It's actually not required to use the interface method for defining service contracts (i.e. you could stick the attributes
directly on the class), but it's the recommended way, and it makes client applications much easier to implement if
they can simply share the same interfaces.

Surprisingly, there's actually very little code required to make the server fully functional. We'll begin by creating a
ServiceHost, which is responsible for most of the work behind exposing the service to clients.

The most difficult thing here is the array of Uri objects. These are our base addresses that clients can use to connect
to this WCF server. Like I said before, we're exposing two ways to connect to this service: http and named pipe. How
the address is formatted depends on the type of Binding it represents.

Now that we've got our ServiceHost created, we need to configure some endpoints. These will actually enable the
http and named pipe bindings and give them the address required by the client.

Here we're adding two endpoints - one for http and one for named pipe. The address that's passed in is what appears
after the base address specified in the ServiceHost constructor (e.g. for http it would be:
"http://localhost:8000/Reverse"). We have to specify a base address for each endpoint we're configuring. So if the
net.pipe base address was not present in the ServiceHost constructor, the server would throw an exception when it
attempted to create the named pipe endpoint. After the endpoints are configured, we simply call Open on the
ServiceHost to enable it.
Now we can move on to the client. The first thing we'll need in the client code is the same interface, with the same
attributes, that we defined in the server. If this were being used in a production environment, these interfaces would
probably be created in a dedicated library that could be easily distributed. For now, I just copied and pasted the code
into another project.

We have to first establish a channel between the client and a server. A channel is basically a connection that allows
the client and server to send messages to each other. Fortunately, WCF provides something called a
ChannelFactory that makes creating these very simple. Incredibly, we're now done with the client. Here's the client
program in its entirety:

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace WCFClient
{
  [ServiceContract]
  public interface IStringReverser
  {
    [OperationContract]
    string ReverseString(string value);
  }

  class Program
  {
    static void Main(string[] args)
    {
      ChannelFactory<IStringReverser> httpFactory =
        new ChannelFactory<IStringReverser>(
          new BasicHttpBinding(),
          new EndpointAddress(
            "http://localhost:8000/Reverse"));

      ChannelFactory<IStringReverser> pipeFactory =
        new ChannelFactory<IStringReverser>(
          new NetNamedPipeBinding(),
          new EndpointAddress(
            "net.pipe://localhost/PipeReverse"));

      IStringReverser httpProxy =
        httpFactory.CreateChannel();

      IStringReverser pipeProxy =
        pipeFactory.CreateChannel();

      while (true)
      {
        string str = Console.ReadLine();
        Console.WriteLine("http: " +
          httpProxy.ReverseString(str));
        Console.WriteLine("pipe: " +
          pipeProxy.ReverseString(str));
      }
    }
  }
}
We're building two proxies here - one for http and one for named pipe. The addresses passed into the
ChannelFactory constructor are the same as those configured on the server. We also have to pass in the specific
bindings we want: BasicHttpBinding and NetNamedPipeBinding. Lastly we call CreateChannel on each channel
factory, which returns an IStringReverser interface. Now we can call functions on those interfaces and WCF
makes a remote call through the channel to our server to get the result.

It's amazing when you think about the amount of stuff happening behind the scenes that developers no longer have
to worry about. Basically, all developers have to do is define interfaces and objects and WCF takes care of the rest.
The server side and client side code can be drastically reduced by using configuration files to replace the setup we
did in code, but for the purpose of understanding, explicitly setting it is a good way to know what's behind
configuration settings.

Events and Callbacks

In our previous WCF Tutorial, we described how to make a very simple client/server application where clients would
call functions on the server through a shared interface. In this tutorial, I'm going to expand that application to allow the
server to execute functions on the client by using callbacks. Essentially, this is WCF's mechanism to allow events to
be raised from the server to it's connected clients.

This post will be utilizing the example applications produced from the first one, so some explanation may be left out.
All right, let's get into it. Just like with a Service Contract, we need to define an interface that describes available
functions that the server can use for callbacks.

All right, let's get into it. Just like with a Service Contract, we need to define an interface that describes available
functions that the server can use for callbacks.

using System;
using System.ServiceModel;

public interface ICallbacks


{
  [OperationContract(IsOneWay = true)]
  void MyCallbackFunction(string callbackValue);
}

Here we've defined an interface with a single function, MyCallbackFunction. We add the OperationContract
attribute to the function and mark it as a one-way operation. What we just did is tell the server that it can now execute
this function on connected clients.

Unlike a Service Contract, it's now up to the client to implement the interface to give it some functionality. In essence,
we're simply doing the exact opposite that was done in the previous tutorial.

public class Callbacks : ICallbacks


{
  public void MyCallbackFunction(string callbackValue)
  {
     Console.WriteLine("Callback Received: {0}", callbackValue);
  }
}

The first thing we need to do is modify the ServiceContract attribute slightly to indicate the existence of a callback
contract. We added two things to the Service Contract. First we need to make sure WCF maintains session
information for the duration of a client's connection. This is required for callback contracts. Secondly, we specify the
which interface will be handling the callback contract.

[[ServiceContract(SessionMode=SessionMode.Required,CallbackContract=typeof(ICallbacks)
)]
public interface IStringReverser
{
  [OperationContract]
  string ReverseString(string value);
}

Normally you'd probably use callbacks a little differently, but I'm going to raise the callback whenever the client calls
ReverseString. I'm also going to pass the result of ReverseString through the callback.

public class StringReverser : IStringReverser


{
 public string ReverseString(string value)
 {
   char[] retVal = value.ToCharArray();
   int idx = 0;
   for (int i = value.Length - 1; i >= 0; i--)
     retVal[idx++] = value[i];

   ICallbacks callbacks =
      OperationContext.Current.GetCallbackChannel<ICallbacks>();

   callbacks.MyCallbackFunction(new string(retVal));

   return new string(retVal);


 }
}

The first thing I do is request the current callback channel to get an instance of my callback interface. Now, whenever
the server calls functions in the callback interface, they will be executed on the client.

The recommended way to handle callbacks is using a subscription model. Instead of getting the callback channel in a
method like this, the service contract should expose a function called Subscribe that can be called by a client.
When called, the callback interface should be created like above, then added to a collection for use later. I
implemented it this way to keep the examples as clean as possible.

We're almost there. Unfortunately, not every binding will support duplex communication. In our previous tutorial we
created a ServiceHost with two bindings: HTTP and Named Pipe. The basic http binding does not support callbacks,
however named pipe will, so for this tutorial I have removed the http bindings.
The real code changes come in initializing a client connection, however they are minor. Originally we were using a
ChannelFactory to create our proxy to the server, however ChannelFactory doesn't support duplex
communication. We're going to have to upgrade to a DuplexChannelFactory.

static void Main(string[] args)


{
  Callbacks myCallbacks = new Callbacks();

  DuplexChannelFactory<IStringReverser> pipeFactory =
     new DuplexChannelFactory<IStringReverser>(
        myCallbacks,
        new NetNamedPipeBinding(),
        new EndpointAddress(
           "net.pipe://localhost/PipeReverse"));

  IStringReverser pipeProxy = pipeFactory.CreateChannel();

  while (true)
  {
    string str = Console.ReadLine();
    Console.WriteLine("pipe: " +
      pipeProxy.ReverseString(str));
  }
}

The first thing I do is create an instance of my Callback class to handle the server's events. Next I simply create a
DuplexChannelFactory object. The constructor is nearly identical to the ChannelFactory used in the previous
tutorial, except now it excepts an object that will be handling the callbacks. Everything after this point is exactly the
same as before.

Now when the client calls ReverseString the callback will be raised before the function returns, so the console
output will look something like below when the client sends the string "My Reversed Text".

Callback Received: txeT desreveR yM


pipe: txeT desreveR yM

Using Properties in Service Contracts:

you'll notice all of the Service Contracts are implemented with interfaces containing only methods. For the longest
time I thought that's all that was supported, until I thought about it a little more. In C# land, properties are simply
wrappers around a get method and set method, so why wouldn't we be able to use properties in a service contract?
Well the answer is we can. This means, all we have to do is move the attribute to above the get keyword.

[ServiceContract]
public interface IStringReverser
{
  string LastReversedString
  {
    [OperationContract]
    get;
  }

  [OperationContract]
  string ReverseString(string value);
}

If property doesn't have the OperationContract attribute, it won't be available through a WCF Service. You might
initially think to just throw the attribute above the property, but doing so would result in this compile-time error. That
makes sense, since the property is not a method. What is a method, though, is the get portion of that property. This
means, all we have to do is move the attribute to above the get keyword.

Overloading Methods:

In our introductory WCF tutorial, I created a basic service contract that accepted a string and returned a reversed
version of it. For this tutorial, I want to overload this function to also accept a character array. If I were to attempt to
just stick in my overload like this:

[ServiceContract]
public interface IStringReverser
{
  [OperationContract]
  string ReverseString(string value);

  [OperationContract]
  string ReverseString(char[] value);
}

It would result in this exception being thrown at runtime:

Cannot have two operations in the same contract with the same name, methods
ReverseString and ReverseString in type WCFServer.IStringReverser violate this rule.
You can change the name of one of the operations by changing the method name or by
using the Name property of OperationContractAttribute.

By default, every operation contract gets a name that is set to the name of method. In WCF, you cannot have two
operation contracts with the same name. Fortunately, this is very easy to fix by simply setting the name property of
the operation contract attribute.

[ServiceContract]
public interface IStringReverser
{
  [OperationContract(Name = "ReverseStringFromString")]
  string ReverseString(string value);

  [OperationContract(Name = "ReverseStringFromCharArray")]
  string ReverseString(char[] value);
}
And there you have it. We now have a WCF service contract with overloaded methods.

You might also like