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

Configure your Customer lookup and run it on IIS 7.0

In the previous article we saw how to use WCF (a basic approach) and what we should keep in consideration if we want to use SOA as our repository.

Now we need to:

  1. Change the WCF service to point to a real database
  2. Test the service
  3. Build a web site to host our service
  4. Host the web site on IIS 7.0
  5. The the final result

Change the Customer service to reflect our database.

First of all let’s open the ServiceLibrary project and change the ICustomerService interface to reflect this:

  1: [ServiceContract]
  2: interface ICustomerService {
  3: 
  4:  [OperationContract]
  5:  IList<CustomerDto> GetCustomers();
  6: 
  7:  [OperationContract]
  8:  IList<CustomerDto> GetFilteredCustomers(string searchCriteria);
  9: 
 10: }

For our menu we need two methods. The first one will retrieve all the available customers, in alphabetical order; the second one will filter this results, in order to show us only the customers that match our search criteria.

The concrete implementation of this contract will consequently change in this way:

  1: List<CustomerDto> Customers = new List<CustomerDto>();
  2: IRepository customerRepository = 
  3:    new Repository(new ADVConnection());

Of course, in order to declare our Repository we need to add a reference to the DataLayer project in our WCF service. We need also to reference the entity framework .dll “System.data.entity” and we need also to add the connectionString section in the app.config of our WCF service, otherwise when we will instantiate a new database session (new ADVConnection()) the Visual Studio will throw an error “configuration not found … ”. This happens because the WCF is the final layers so you can use in .NET just one config file in the final layer (UI).

Now, what we want to do, is to populate the list of customer, in our service library, with the customers available in the database. Because our service is a singleton, we will do that when the first user will call the service:

  1: public CustomerService() {
  2:     var result = from c in customerRepository.GetAll<Customer>() orderby c.FirstName, c.LastName select c;
  3:     foreach (var customer in result) {
  4:         Customers.Add(
  5:             new CustomerDto() { 
  6:                 Id = customer.CustomerID, 
  7:                 FullName = customer.FirstName + " " + customer.LastName
  8:             }
  9:         );
 10:     }
 11: }
 12: 
 13: 

Now, this piece of code is pretty easy and ugly. We should use something like AutoMapper to populate on fly our DTO but I want to show you  exactly what happens behind the scene.

We takes all the available customers from the database and one by one, we fill up the Dto with the resultset.

A niece solution here would be also to use an extension method and do something like “from c in customers select c.ToDto()” that may returns a IList<CustomerDto>. Wink

The two methods will change consequently in this way:

  1: public IList<CustomerDto> GetCustomers() {
  2:     return Customers;
  3: }

And the filtered version will change in this way:

  1: public IList<CustomerDto> GetFilteredCustomers(string searchCriteria) {
  2:  return Customers.FindAll(
  3:   delegate(CustomerDto c) { 
  4:    return c.FullName.ToLower()
  5:     .Contains(searchCriteria.ToLower()); 
  6:   }
  7:  );
  8: }
  9: 

We just said to the List “Hey, looks inside the items and whether the items lower case contains this word, keep it”. Using this approach will allow us to keep clean the in memory list of customers and retrieve only the customers that match the criteria.

Test the environment.

Now if we press F5 our project will compile but when we will try to call the GetCustomers, we will receive this error:

imageVisual Studio is pretty nasty in this, because whatever you will say in the app.config, it will use a different app.config “on fly” when you test your service. So in the service windows, click on the app.config under the customer service and change it in this way:

imageBy default WCF doesn’t allow to carry out more than  few bytes on our messages, but because we are retrieving a list of 800 entities … we should increase this parameter.

Remember that everything has a cost in resources and it is not a good practice to send and receive a lot of megabytes of message content.
Consider using pagination and other tricks.

Now we need to expose this service on a web site. Why? Because when we will develop the UI we will add a reference to an host web site service, like http://raffaeu.com/service/Customer.svc and not to a dev address like http://localhost:9080/PrismTutorial… Smile

Create a host web site and install it on IIS 7.

We need to add a new web site application on our solution, but it has to be a WCF Service web site solution, like the picture below:

imageDelete all the content except the service.svc file and the web.config.

First add a new reference to our project ServiceLibrary.

Then add the connection string to the web.config file.

Finally, change the service.svc to customer.svc and change the HTML code in this way:

  1: <%@ 
  2:    ServiceHost Language="C#" 
  3:    Debug="true" 
  4:    Service="PrismTutorial.ServiceLibrary.CustomerService" 
  5: %>

Cool, now let’s modify the web.config of our WCF web site and we are done.

imageI just said to the new endpoint to point to our .dll service library and to expose the contract IServiceContract. The same step we did previously to the service library layer.

If you now press F5 you can see the process running under ASP.NET. Of course we need to install it on IIS in order to have a common address for our future services. Because the web site points to our project, every time we will change the WCF library this will automatically change in the web service. Of course when we will create new contracts we will need to define new endpoint in both layers.

Note: if you have, like me, Windows 7 and you want to follow this step, you need to install and configure IIS 7 and WCF for IIS. You can do that by following this simple and useful post.

Open IIS 7 and install the new application by creating a new application that will point to our project:

image If everything is ok, you will be able to browse the folder of this web.app, click on the .svc file, and select Browse.

You should get this result:

image

Considerations.

This tutorial shows how to create and host a WCF service using Visual Studio and IIS 7. Starting from the next tutorial I will not show you anymore this part as you can use this article as a reference.

We will create new services and contracts and we will call them asynchronously inside WPF UI.

I use this approach to get the data on my applications as I can manage better the points of failure of my applications and keep the code separated and clean. If something change on the customer service I can simply add a new method and all the previous versions of my software will continue to work. If my WCF service crashes I can change the web app to point to a different .dll and everything will continue to work.

Stay tuned as from the next time we will start to build the UI. We will talk about Prism, regions IoC and more.

Tags: