Exposing any class as a WCF endpoint…


Often, I’ll have a customer that wants to utilize a new feature in the .NET framework
but they don’t necessarily know where to start or they have a large investment in
another area and they’re afraid of the amount of rework required to get something
working.  This week, for example, I was teaching a customer about WPF and they
asked:

“We have several class libraries and we’d like to expose them as WCF services. 
How can we do it?”

Yes, it was a bit off-topic from WPF but not really.  I’ve found that when a
customer chooses to start investing in a newer technology, like WPF, I’ve found that
they also want to look at ways to revamp their existing applications to use other
new features.  But I digress…

In pre-.NET 4.0, if you wanted to expose a class as a WCF endpoint and make it available
in IIS as an SVC file, you would have to do the following:

  1. Create a new WCF Service (in the same category as WebSite).
  2. Add  a bunch of new “WCF Service” classes (files with an extension of “.SVC”).
  3. Write some code to call out to your existing class library from the WCF Service.

It’s not exactly a painful experience but would require a bit of work to get everything
up and running.  In many cases, if you have a huge investment in something like
a class library, the amount of work may be incredibly daunting.  Fortunately,
using some of the features in WCF 4 (part of .NET 4), this type of story is ridiculously
easy.  The steps that we’ll follow are the following:

  1. Decorate your existing class.
  2. Add configuration.
  3. Deploy to IIS

Then, I’ll discuss additional options for debugging your new service.

Step 1:  Decorate your existing class

So, I’m sure we all have a class in some Class Library somewhere that looks like this:

public class MyBusinessLogic
{

public string GetName(int id)
{

return "My ID is: " + id;

}

public MyDataClass GetEmpInformation(int id)
{

return new MyDataClass()
{
FirstName = "Greg",
LastName = "Varveris",
Occupation = "Developer"
};


}
}

This is just a simple little business logic class that exposes two public methods
– GetName and GetEmpInformation.  So, let’s say we wanted to make this class
accessible as a WCF service.  The first thing we need to do is add a reference
to the .NET 4 version of System.ServiceModel in our Class Library project. 

image

I’ve included a screenshot to our left just to further show that there is no special
sauce here.  All of the assemblies being referenced in this project are straight
up class library defaults.  Now that we have the assembly referenced, let’s decorate
our class with two attributes:

  • ServiceContract – This decorates our class and tells .NET that we have a WCF Service.
  • OperationContract – This decorates our methods and tells .NET which methods/functions
    we want to expose in our service.

The decorated class will now look like:

[ServiceContract]
public class MyBusinessLogic
{

[OperationContract]
public string GetName(int id)
{

return "My ID is: " + id;

}

[OperationContract]
public MyDataClass GetEmpInformation(int id)
{

return new MyDataClass()
{
FirstName = "Greg",
LastName = "Varveris",
Occupation = "Developer"
};


}
}

And really that’s all you have to do from the code side.

Step 2:  Add Configuration

WCF configuration has always been synonymous with “WOAH” before.  Even using
the great configuration editor tool, you may end up with a large amount of XML in
your .config file.  This is mostly because WCF is just so darn extensible. 
Well, for our scenario, we’ll use some great new features in WCF 4 to make the configuration
a breeze:

  • File-less Activation
  • Default Configuration model

You can read-up about
each of these features in the nice MSDN documentation.
Basically, WCF 4 exposes
the ability to map a file-name to a class and then it can expose a default endpoint
(using BasicHttpBinding).  For our scenario my entire config file is:

<configuration>
<system.serviceModel>
<serviceHostingEnvironment>
<serviceActivations>
<add relativeAddress="MyBusinessLogic.svc" service="WCFSample.Library.MyBusinessLogic"/>
</serviceActivations>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

That’s it.  In the first snippet, we are adding a relative address of “MyBusinessLogic.svc”
which will point to our MyBusinessLogic class we defined above.  The second section
along the bottom is just to enable the service metadata. 

The only minor manual snafu you’ll need to handle is that Visual Studio won’t let
you add a web.config to a Class Library project.  This can be easily remedied
in a variety of ways.  I just added an app.config to my project and then changed
the name from “app.config” to “web.config”.  Then, you just need to tell it to
Copy to the output directory.  This makes our project look like the following:

image

Step 3:  Deploy to IIS

Now that we have our minuscule configuration and trivial decorations to our class,
we need to host our service somewhere.  For this, we’ll just use IIS with an
ASP.NET 4.0 application pool.  The structure of this folder will need to have
the assemblies in a “bin” folder and the web.config in the root.

image

The bin folder is required so that the IIS engine can find your assembly.  Once
you configure this in IIS, you can simply navigate to your service (make sure you
include the SVC in your url) in a browser and you’ll see the glorious WCF Service
start page. For example, on my machine, when I navigate to: http://localhost/SampleWCFService/MyBusinessLogic.svc, I’ll
see:

image

Debugging your service

So you have created your service, added configuration to it and deployed it to your
hosting environment and everything is running smoothly.  What if you want to
debug the service in Visual Studio?  Well, you really have 3 different options:

  1. Attach to the instance of w3wp hosting your WCF service.
  2. Cassini…errr, the ASP.NET Development Server.
  3. IIS Express

I personally prefer either options 2 or 3 as it provides that seamless debugging experience
we all crave where we just hit the “Green Arrow” to start the debugging session. 
With either option you select, we’ll need to make one or two minor configuration changes.

First, we’ll need to tell the solution to start our process.  For this, you can
right-click on your solution file in the Solution explorer and select “Properties”. 
In this window, you’ll need to select the Multiple Startup Projects radio button and
set both of your projects (the Client and the Service) to the “Start” option.

image

Second, you’ll need to add a pre/post-build step for your service to structure the
output folder correctly.  Since we will deleting the contents of the “Bin” folder
wherever our assemblies are being output, the command we will use is:

if exist "$(TargetDir)bin" del /q "$(TargetDir)bin\*.*"

Then, for our post-build step, we will need to create the bin folder if it doesn’t
exist and then copy over our DLL’s into that bin folder.  Those commands will
be:

if not exist "$(TargetDir)bin" mkdir "$(TargetDir)bin"

copy "$(TargetDir)\*.dll" "$(TargetDir)\bin"

copy "$(TargetDir)\*.pdb" "$(TargetDir)\bin"

del "$(TargetDir)\*.dll"

del "$(TargetDir)\*.pdb"

That will take our output directory from zero to hero quite nicely:

image

Now that the prerequisites are met, we just need to point our local hosting tool (either
the Development Server or IIS Express) at that folder.  We’ll do this in the
Debug tab of the project properties.   Set the “Start External Program”
radio button and set the path to:

C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\WebDev.WebServer40.EXE

Then, in the Command Line Arguments, specify the following:

/port:12345

/path:"<path to folder containing bin & web.config>"

/vpath:/myservice

Then, you can set a Service Reference on whatever vpath you chose above.  For
example, my service reference points to:  http://localhost:12345/myservice/MyBusinessLogic.svc

Once the service reference is set, you can just hit the fancy green arrow to start
debugging:

image

Enjoy!


Comments (0)