KISS Architecture (part 14)

by Chris 27. February 2009 16:26

This is a follow-up on my blog series (see last part) on the mobile blog Windows Mobile Development about creating a simple architecture that make use of the latest technologies in the simplest way.

KISS Architecture Silverlight Client The implemented architecture is published on CodePlex in a project called KISS Architecture, and this means that you can access the full source code as well as discuss it, come with suggested improvements, etc. As I walk you through the implementation, I suggest you keep the source code handy to check out more details.

In this post I will show how a Silverlight 2 client can be implemented to use the KISS architecture. First, make you have the necessary tools installed to develop for Silverlight 2. I start by creating a "Silverlight Application" project named Kiss.Silverlight, and when asked also add a Web application named Kiss.Silverlight.Web to host the Silverlight application. When the project is created, I add a service reference to the service (see part 7 for details) named OrderService.

Now, let's implement a simple user interface by adding five controls (a TextBlock named cityTextBlock, a TextBox named cityTextBox, two buttons named getButton and updateButton, and a DataGrid named simply dataGrid) to the automatically generated page (renamed MainPage.xaml). The result should look similar to the figure on the left.

The page markup should look something like this:

<UserControl x:Class="Kiss.Silverlight.Page"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  
Width="600" Height="400" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
   xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="35"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBlock HorizontalAlignment="Left" Margin="8,16,0,0" VerticalAlignment="Top" Text="City:"
           TextWrapping="Wrap" Width="58.652" Height="18" x:Name="cityTextBlock"
           d:LayoutOverrides="VerticalAlignment, Width"/>
        <TextBox Height="22" HorizontalAlignment="Left" Margin="43,12,0,0" x:Name="cityTextBox"
           VerticalAlignment="Top" Width="174" Text="" TextWrapping="Wrap"/>
        <Button HorizontalAlignment="Left" Margin="221,12,0,0" x:Name="getButton" Click="getButton_Click"
          VerticalAlignment="Top" Width="52" RenderTransformOrigin="0.07,0.636" Content="Get"
          d:LayoutOverrides="HorizontalAlignment"/>
        <Button HorizontalAlignment="Left" Margin="277,12,0,0" x:Name="updateButton" Click="updateButton_Click"
          VerticalAlignment="Top" Width="52" RenderTransformOrigin="0.07,0.636" Content="Update" />
        <data:DataGrid Margin="8,8,8,8" Grid.Row="1" x:Name="dataGrid" AutoGenerateColumns="True"/>
    </Grid>
</
UserControl>

With the service reference and the user interface in place, it's time to implement some presentation logic. Here's the code for the "Get" button:

private void getButton_Click(object sender, RoutedEventArgs e)
{
   
OrderServiceClient service = new OrderServiceClient();
    service.Endpoint.Address =
new System.ServiceModel.EndpointAddress("http://localhost:2222/OrderService.svc");
    service.GetCustomersByCityCompleted +=
        new EventHandler<GetCustomersByCityCompletedEventArgs>(service_GetCustomersByCityCompleted);
    service.GetCustomersByCityAsync(cityTextBox.Text);
}

private void service_GetCustomersByCityCompleted(object sender, GetCustomersByCityCompletedEventArgs e)
{
    dataGrid.ItemsSource = e.Result;
}

Note how easy it would be to redirect the client to use the service in another location (local, server, cloud, etc) by just changing the service URI. Also note how the definition of the entity (Customer) have come all the way from the data service without any manual coding anywhere, and when it is changed, it's simply a matter of updating the service references in all tiers. As you should never make a synchronous call with Silverlight 2 (as this would freeze the browser completely), a callback method is defined before the asynchronous call is made. It's this callback method that fill the grid with the returned result (list of customers).

The observant will note that the List<Customer> return value of the service is transformed into a plain array when serialized by WCF, but if a list is preferred, this code could be used:

List<Customer> customers = service.GetCustomersByCity(cityTextBox.Text).ToList();

The code for the "Update" button looks like this:

private void updateButton_Click(object sender, RoutedEventArgs e)
{
   
OrderServiceClient service = new OrderServiceClient();
   
Customer customer = (Customer)dataGrid.SelectedItem;
    customer.City = customer.City + "X";
    service.UpdateCustomerCompleted += new EventHandler<AsyncCompletedEventArgs>(service_UpdateCustomerCompleted);
    service.UpdateCustomerAsync(customer);
}

private void service_UpdateCustomerCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{          
}

It takes the customer entity in the selected row in the grid, and adds an "X" to the City attribute. Then the service is called asynchronously (just as with the get above) with the updated entity instance (customer). It can't be much simpler than this! Actually, we would need the callback, but it would probably come in handy if we wanted to play an animation (like a wait indicator) while we waited for the update to complete.

As the same technology is available on the (Windows) client, the full architecture (with all its tiers) can be run locally and thereby enabling offline mode (e.g. when not network connection exist). In this scenario, it would be beneficial to use the Sync Framework for data synchronization, and that framework will probably also be involved in the upcoming "offline" version of ADO.NET Data Services (see the Astoria team blog for more info).

In the next part, I will sum up this series about the KISS architecture.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Architecture | Code | Silverlight

Comments

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About me

Chris ForsbergChris Forsberg
Microsoft developer, author, and fan of technology More...