A Walkthrough of WCF Support in Visual Studio 2008

One feature in Visual Studio 2008 I would like to highlight is our support of Windows Communication Foundation. WCF was introduced with .NET Fx3.0 as a next generation communications API. Previously if you wanted apps to talk you needed to make a lot of up-front decisions:


How important is transmission speed?
o How will apps talk? Over the internet, intranet, or on the same machine?
o Is reliable messaging important?
o Is message encryption important?

Once you made those decisions and started writing your app you were forced to learn a new protocol {.Net Remoting, ASMX web services, MSMQ, Named Pipes, etc.} and implement a solution specific to that API. The problem with this is that your code doesn’t age gracefully. If the requirements change too much, you need to rewrite the entire communication layer using an API which supports whatever mission-critical feature you need.

WCF fixes this problem and more by providing a unified programming model for all the above scenarios so you now just have to learn one API and toolset. It does this by separating the various pieces of communication, E.g., protocols, message contracts, etc. Rather than worrying about the specifics of how each message is transferred between client and server, WCF just asks you to focus on the service and message contracts. That is, what methods will you be able to call from a client and the structure of the data returned. All the goo about communication protocols is highly configurable and out of code (in the app.config). That is WCF from a mile-high view, but let’s dive into what it can do for you in Visual Studio 2008.

We will be creating a three-tiered application called Northwind Traders. Our solution will comprise of four projects: a data access layer, a WCF service, a WinForms client, and a shared business logic component. Along the way we will highlight key features new to Visual Studio 2008 and demonstrate just how easy it is to write killer data-centric apps.

Creating Data Access Layer

Let’s start our app by creating a data access layer by creating a new class library aptly titled DataAccessLayer.

One of the common problems developing N-tier applications in Visual Studio, is that the tools put the TableAdapters and the typed DataSets in the same project. Which unfortunately leaks out sensitive information such as connection strings. If you wanted to reuse your typed DataSets but keep your TableAdapters private, you have to resort to fighting against the tools which doesn’t provide a great developer experience. Fortunately in Visual Studio 2008 we’ve addressed this.

Once you’ve created the data access layer in Visual Studio 2008 you can configure the DataSet Designer to generate the DataSet code into a separate project in your solution. So you can share/reuse your typed DataSets without exposing things like connection strings.

Add another class library project to your solution called NorthwindBuisnessObjects.

DataSet into Diff Project

Then, reopen the NorthwindDataSet and change the ‘DataSet Project’ property on the properties window to be NorthwindBuisnessObjects. Now, once you build your project, NorthwindDataSet.DataSet.Designer.vb will be generated in the NorthwindBuisnessObjects project.

Next let’s add some simple validation logic to our DataSet. Double click the DataSet designer and insert the following code snippet. (Note that it automatically creates DataSet.vb in the correct project.)

Partial Class NorthwindDataSet

    Partial Class OrdersDataTable


        Private Sub OrdersDataTable_OrdersRowChanging(ByVal sender As System.Object, ByVal e As OrdersRowChangeEvent) Handles Me.OrdersRowChanging


        End Sub


        Private Sub OrdersDataTable_ColumnChanged(ByVal sender As Object, ByVal e As System.Data.DataColumnChangeEventArgs) Handles Me.ColumnChanged

            If e.Column.ColumnName = Me.OrderDateColumn.ColumnName Or e.Column.ColumnName = Me.ShippedDateColumn.ColumnName Then


            End If

        End Sub





        Private Sub ValidateDates(ByVal row As OrdersRow)

            If row.OrderDate > row.ShippedDate Then

                row.SetColumnError(Me.OrderDateColumn, “Can’t ship before it’s been ordered”)

                row.SetColumnError(Me.ShippedDateColumn, “Can’t ship before it’s been ordered”)


                row.SetColumnError(Me.OrderDateColumn, “”)

                row.SetColumnError(Me.ShippedDateColumn, “”)

            End If

        End Sub

    End Class

End Class


Let’s finish our data access layer by adding a class called NorthwindManager, which connects to the database and returns our tables.


Imports NorthwindBuisnessObjects


Public Class NorthwindManager


    Public Shared Function GetCustomers() As NorthwindDataSet.CustomersDataTable


        Dim customerAdapter As New NorthwindDataSetTableAdapters.CustomersTableAdapter()


        Return customerAdapter.GetData()


    End Function


    Public Shared Function GetOrders() As NorthwindDataSet.OrdersDataTable


        Dim orderAdapter As New NorthwindDataSetTableAdapters.OrdersTableAdapter()


        Return orderAdapter.GetData()


    End Function


End Class


Creating a WCF Service

Now let’s move onto creating our WCF service. The tooling support should be on par with the ASMX Web Reference experience. Let’s begin by creating a new WCF Web Service project, which creates a new WCF service hosted in IIS.

New Website Dialog

Note that WCF doesn’t have to just be a web-based service. In Visual Studio 2008 we also have project templates for service libraries, which are WCF services baked into class libraries. In addition we have a Test Form which allows you to debug you WCF services (not discussed here).

Once our service project has been created, let’s add references to both our DataAccessLayer and BuisnessObjects projects.

Next, let’s replace the default service contract from the project template with our own. Those <ServiceContract()> and <OperationContract()> interfaces indicate to the WCF runtime that this is a WCF service contract.

Imports NorthwindBuisnessObjects


<ServiceContract()> _

Public Interface IService


    <OperationContract()> _

    Function GetCustomers() As NorthwindDataSet.CustomersDataTable


    <OperationContract()> _

    Function GetOrders() As NorthwindDataSet.OrdersDataTable


End Interface

Let’s change the service contract implementation accordingly.

Imports NorthwindBuisnessObjects

Imports DataAccessLayer


Public Class Service


    Implements IService


    Public Function GetCustomers() As NorthwindDataSet.CustomersDataTable Implements IService.GetCustomers