August 30th, 2007

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:

o

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

                ValidateDates(e.Row)

            End If

        End Sub

 

        ‘*********************************************

        ‘CUSTOM VALIDATION CODE FOR MY DATASET

        ‘*********************************************

        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”)

            Else

                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

 

Author

0 comments