Build enterprise application with WPF, WCF, Entity Framework and Prism. Tutorial 05.

Update: source code and documentation are now available on CodePlex at this address: http://prismtutorial.codeplex.com/

Starting with WCF.

Today we will see how WCF works and what are the best practices we should use in order to keep our application safe and maintainable.

WCF startup.

I assume that you know already what is WCF and what’s the difference between WCF and the old Web Service technology. If you don’t, this is a nice overview of WCF, and this is a nice overview of the differences from these 2 technologies.

The big difference from using a normal data access layer and a SOA service is in the architecture. We must keep in consideration, always, that we are working with a message service and that all the information are serialized and passed through the network. This point it’s really important because the most common error I saw using WCF is to serialize directly the entities in the domain model …

Let’s keep as an example our Customer entity.

image

We have a lot of information in this graph and I am pretty sure that we will use those information only when we will look at the details of each customer, so it completely doesn’t make any sense to carry all these information with us for all the time.

Let’s have a break and let’s see what will be the final result of our application using a sketch. (I use Microsoft Expression Blend sketch available for trial here). The style is modified by me to reflect Balsamiq, another Sketch flow design software.

myImage

What we will do, when the navigation bar will be open to the Customer section, we will load a list of Customers, but we need only the Id and a FullName that will represent the customer. Then if the user will click on a customer, we will load an additional view with all the details. To accomplish this data transformation we will use a Dto (Data transfer object)

“The Data Transfer Object “DTO”, is a simple serializable object used to transfer data across multiple layers of an application. The fields contained in the DTO are usually primitive types such as strings, boolean, etc. Other DTOs may be contained or aggregated in the DTO.”

directly inside WCF. In this way we will have a light version of our customer entity that will be carried over the network.

Customer Dto.

Let’s create a new WCF project in our solution and add a new class. The class will be a serialized light version of our Customer entity.

  1: using System.Runtime.Serialization;
  2: 
  3: namespace PrismTutorial.WCF {
  4: 
  5:     [DataContract]
  6:     public class CustomerDto {
  7:         [DataMember]
  8:         public int Id { get; set; }
  9:         [DataMember]
 10:         public string FullName { get; set; }
 11:     }
 12: }
 13: 

First of all, the DataContract attribute. This attribute identifies the entity CustomerDto as serializable. Through the attribute DataMember we are saying that both the Id and the FullName properties will be serialized.

In order to use this Dto, we need a service contract that will allows us to do some simple operations with the Dto. The service contract will expose the operations that we will allow to the end user.

Let’s add a new interface on our WCF project that will look in this way:

  1: using System.Collections.Generic;
  2: using System.ServiceModel;
  3: 
  4: namespace PrismTutorial.WCF {
  5: 
  6:     [ServiceContract]
  7:     interface ICustomerService {
  8:     
  9:         [OperationContract]
 10:         void AddCustomer(CustomerDto customer);
 11:         
 12:         [OperationContract]
 13:         void DeleteCustomer(CustomerDto customer);
 14:         
 15:         [OperationContract]
 16:         IList<CustomerDto> GetCustomers();
 17:     
 18:     }
 19: }
 20: 

The two attributes that we use now are ServiceContract and OperationContract. The first one will identify the Interface as a WCF contract. Using this attribute we are going to say to WCF: “Hey this is the contract that I want to expose, so let’s look inside and see if there is anything useful for you”.

The second attribute is identifying our method as visible to the contract. Of course we can have also some methods that we want to include in the service but that we don’t want to expose to the public.

After that we need to implement in a concrete class our contract and implement the operations. This is just an example so we will have an internal IList of Dto and we will use the operations just to interact with the list exposed by the service.

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Web;
  5: using System.ServiceModel;
  6: 
  7: namespace PrismTutorial.WCF {
  8:     [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
  9:     public class CustomerService : ICustomerService {
 10: 
 11:         IList<CustomerDto> Customers = new List<CustomerDto>();
 12: 
 13:         #region ICustomerService Members
 14: 
 15:         public void AddCustomer(CustomerDto customer) {
 16:             Customers.Add(customer);
 17:         }
 18: 
 19:         public void DeleteCustomer(CustomerDto customer) {
 20:             Customers.Remove(customer);
 21:         }
 22: 
 23:         public IList<CustomerDto> GetCustomers() {
 24:             return Customers;
 25:         }
 26: 
 27:         #endregion
 28:     }
 29: }
 30: 

The only notable thing here is the attribute ServiceBehavior that explains how our service will be created.  In this case we said that the first call will activate the service, so it’s like using a SingleTon pattern. Of course the service behavior attribute has a lot of options.

We can also use this code in order to be sure that our entity will be correctly removed. Change the intenal IList to a List<T> and change the DeleteCustomer method in this way:

  1: public void DeleteCustomer(CustomerDto customer) {
  2:    Customers.Remove(Customers.Find(
  3:       c => c.Id.Equals(customer.Id))
  4:    );
  5: }
  6: 

Configure the service.

Now that we have our basic service we have to build the solution CTRL+SHIFT+B and then right click on the app.config and select Configure. We will see a window like this one:

imageFirst of all click on service one and point to the compile .dll in order to have the service to Customer Service and not Service1.

Now select the endpoint in the service node and again, change it to point to our .dll and select the ICustomerService.

Now if you press F5 and set the WCF as the startup project, you will be prompt by this windows that is the default test window of Visual Studio 2008 for WCF.

imageBy clicking on a method you will be prompted by a default view that allows us to interact with the service in testing mode.

You can test it by using the addCustomer a couple of times and then the GetCustomers. You will find in the message the customers you previously added.

Considerations.

In this post we saw how WCF works so now we can do our considerations and create the service for each entity or view, it depends on how you want to structure your software. Of course we should do something better like sending a response message each time we do an operation, or get back the changed list of customers each time we do a CRUD operation.

The are also other considerations using WCF and attributes that we didn’t see this time. This will be part of the next tutorial.

Finally, I want to give you some tips using WCF that I have found in the pattern and practices on MSDN web site.

Enjoy this tutorial and stay tuned for the next one!

Tags: