KISS Architecture (part 15)

by Chris 6. March 2009 16:27

This is the final post in this series, and for a complete reference, here are the previous parts:

  • Part 1 was a general introduction
  • Part 2 outlined the architecture (tiers, etc)
  • Part 3 showed the benefit of loosely coupled tiers (distribution, cloud, etc)
  • Part 4 started the implementation by creating the entity data model (using ADO.NET Entity Framework)
  • Part 5 published the entity data model as a data service (using ADO.NET Data Services)
  • Part 6 implemented the business domain (using the data service)
  • Part 7 created the service (using WCF)
  • Part 8 started the implementation of the mobile client (using WCF)
  • Part 9 added offline support to the mobile client (using SQL Server Compact, etc)
  • Part 10 is the summary of the mobile series
  • Part 11 showed a traditional Windows client (using Windows Forms)
  • Part 12 demonstrated a traditional Web client (using ASP.NET)
  • Part 13 implemented a modern Windows client (using WPF)
  • Part 14 created a modern Web client (using Silverlight 2)

The complete 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.

Even if this series now is complete, I will continue to build further on the KISS architecture, and any suggestions on things to add are most welcome. Any other feedback, for that matter, is also warmly welcome!

Be the first to rate this post

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

Tags: ,

Architecture | Code

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

KISS Architecture (part 13)

by Chris 20. February 2009 16:24

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 WPF 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 WPF (Windows Presentation Foundation) client can be implemented to use the KISS architecture. I start by creating a "WPF Application" project named Kiss.Wpf, and then 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 MainWindow.xaml). Note that the DataGrid is included in the WPF Toolkit, that you need to download and install. When run, the result should look similar to the figure on the left.

The page markup should look something like this:

<Window x:Class="Kiss.Wpf.MainWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Kiss.Wpf" Height="400" Width="600" xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="35"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBlock HorizontalAlignment="Left" Margin="8,15,0,0" VerticalAlignment="Top" Text="City:"
           TextWrapping="Wrap" Width="58.652" Height="19" x:Name="cityTextBlock" />
        <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" />
        <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" />
        <my:DataGrid Margin="8,8,8,8" Grid.Row="1" x:Name="dataGrid" AutoGenerateColumns="True"/>
    </Grid>
</
Window>

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 EndpointAddress("http://localhost:2222/OrderService.svc");
   
Customer[] customers = service.GetCustomersByCity(cityTextBox.Text);
    dataGrid.ItemsSource = customers;
}

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. 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.SelectedValue;
    customer.City = customer.City + "X";
    service.UpdateCustomer(customer);
}

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 with the updated entity instance (customer). It can't be much simpler than this!

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 show how a Silverlight 2 client can make use of the KISS architecture.

Be the first to rate this post

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

Tags: , ,

Architecture | Code

KISS Architecture (part 12)

by Chris 13. February 2009 16:22

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 Web 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 normal Web (ASP.NET) client can be implemented to use the KISS architecture. I start by creating a "ASP.NET Web Application" project named Kiss.Web, and then 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 Label named cityLabel, a TextBox named cityTextBox, two buttons named getButton and updateButton, and a GridView named simply gridView) to the automatically generated page (Default.aspx). When run, the result should look similar to the figure on the left.

The page markup should look something like this:

<html xmlns="http://www.w3.org/1999/xhtml" >
<
head runat="server">
    <title>Kiss.Web</title>
</
head>
<
body>
    <form id="form" runat="server">
    <asp:Label ID="cityLabel" runat="server">City:</asp:Label>
    <asp:TextBox ID="cityTextBox" runat="server" />
    <asp:Button ID="getButton" Text="Get" OnClick="getButton_Click" runat="server" />
    <asp:Button ID="updateButton" OnClick="updateButton_Click" Text="Update" runat="server" />
    <asp:GridView ID="gridView" AutoGenerateColumns="true" runat="server"/>
    </form>
</
body>
</
html>

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:

protected void getButton_Click(object sender, EventArgs e)
{
   
OrderServiceClient service = new OrderServiceClient();
    service.Endpoint.Address = new EndpointAddress("http://localhost:2222/OrderService.svc"); 
   
Customer[] customers = service.GetCustomersByCity(cityTextBox.Text);
    gridView.DataSource = customers;
    gridView.DataBind();
}

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. 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:

protected void updateButton_Click(object sender, EventArgs e)
{
   
OrderServiceClient service = new OrderServiceClient();
   
Customer customer = service.GetCustomersByCity(cityTextBox.Text)[0];
    customer.City = customer.City +
"X";
    service.UpdateCustomer(customer);
}

It takes the customer entity in the first row returned by the service (which is also the first one shown in the grid), and adds an "X" to the City attribute. Then the service is called with the updated entity instance (customer). It can't be much simpler than this!

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 show how a WPF (Windows Presentation Foundation) client can make use of the KISS architecture.

Be the first to rate this post

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

Tags: , ,

Architecture | Code

KISS Architecture (part 11)

by Chris 6. February 2009 16:19

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 Windows FormThe 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 simple Windows Forms client can be implemented to use the KISS architecture.

I start by creating a "Windows Forms Application" project named Kiss.WinForm, and then add a service reference to the service (see part part 7 for details) named OrderService.

Now, let's implement a simple user interface by renaming the automatically generated form (Form1) to MainForm, and add five controls (a Label named cityLabel, a TextBox named cityTextBox, two buttons named getButton and updateButton, and a DataGridView named simply dataGrid) to it. The result should look similar to the figure on the left.

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, EventArgs e)
{
   
OrderServiceClient service = new OrderServiceClient();
    service.Endpoint.Address =
new EndpointAddress("http://localhost:2222/OrderService.svc");
   
Customer[] customers = service.GetCustomersByCity(cityTextBox.Text);
    dataGrid.DataSource = customers;
}

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. 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, EventArgs e)
{
   
OrderServiceClient service = new OrderServiceClient
();
   
Customer customer = ((Customer
[])dataGrid.DataSource)[dataGrid.CurrentRow.Index];
    customer.City = customer.City + "X"
;
    service.UpdateCustomer(customer);
}

It takes the customer from the currently selected row in the grid, and adds an "X" to the City attribute. Then the service is called with the updated entity instance (customer). It can't be much simpler than this!

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 show how a Web client (ASP.NET) can make use of the KISS architecture.

Be the first to rate this post

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

Tags: , , , ,

Architecture | Code

I Love Code

by Chris 7. January 2008 10:04

As you may have seen so far, there's a lot of love on my blog ;-)!

Even since I started programming (yes, it was called that back then), I always wanted to share my apps. It was always a great pleasure to see someone starting up you application and start trying it out. When I started to work as a developer, it was natural that my colleges got the code, rather than the binaries, as I wanted feedback both on the app and the code. Then the code sharing got organized within source control, version handling, and even configuration management systems. It was even easier to share, and we worked together on the same code, but I always felt that the tools was a limitation. I've used everything from raw CVS and SourceSafe to ClearCase, and I've had problems with them all.

TeamPlain bug report

First of all, they are no fun! For me, code is fun, and I want my code to stay in a fun place. A place where I can follow its development, its growth, its progress, and even its problems and issues. When I saw the TFS the first time, I thought that Microsoft was on the right track (as usual), and using it was more fun than before. But still, something was missing, and when CodePlex came around, there was an idea of how it could work. Then I saw TeamPlain. They put the extra effort in creating a great UX, and now the code was treated with respect and it was really fun.

Just check out the bug report on the left - that's fun!

I want to follow the progress of my code on a site like this. The fact that it was built on WSS is even better as it gives me even more "for free" (like free-text searching, site management, ability to extend and customize it using a standard approach, etc, etc).

Then, when I saw that Microsoft went and bought the creators, and made it available as a free download called Team System Web Access (TSWA), I was in heaven. Even if there's always more to dream about, there is already a lot to be grateful about too.

I haven't checked out the new features in VS2008 TFS, but I guess I won't be disappointed as I suspect that TSWA is already included.

Be the first to rate this post

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

Tags:

Code

After Code

by Chris 30. October 2007 11:24

Another weekend of hard work is approaching, and it feels great! I have some cool technology to look forward to, like a brand new ASP.NET 3.5 architecture design and Windows Mobile Web Services along with some plain old WinForms and Reporting Services. The blog title comes from an informal event (read; socialize with beer) every late Friday afternoon that I heard of today. The term refers to "After Ski" which is a similar event after a great day of skiing. There are several reason why I think that it's a great term.

First of all, the idea of relaxing after doing something funny all day, like coding, is a nice concept. That is really how I see it! I take both pride and joy in my work as a developer because I create all day long; how many people do that every day? The creation makes us artists, and that is where most of the pride comes from. Another aspect I like is the focus on code, and the "code" of our business is exactly that - code! We are the modern "workers" that create the products that other people use. We are mostly still craftsmen like most professions a few hundred years ago (shoemakers, tailors, etc), even if parts of our "industry" is moving towards an approach focusing more on customization (building with standard products and components). We are the brain-brawn, and I take pride in that too. In Wikipedia's definition of code you find "...code is a rule for converting a piece of information...into another form or representation...", and that is how I see my role as a developer. I convert business information, according to rules, to another (better) form - applications!

Although I will probably not have much "After Code" this weekend, I think it's a great concept ;-)...

Be the first to rate this post

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

Tags: ,

Code | Life

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...