Creating the foundations of your application
Before taking care of the smart client properly speaking, we must set up a data tier. The data tier is the place where the application will persist all of its data and is therefore commonly referred to as the persistence layer. On top of that layer, CodeFluent allows us to generate a middle tier which will contain a set of objects enabling developers to:
1. manipulate the data objects stored in the persistence layer,
2. define the business logic of our application.
Therefore, this middle tier is known as the Business Object Model (BOM). In the end, whatever the user interface or the type of architecture is, the persistence layer (containing the data) and the business layer (containing the business logic) are always the fundamental pillars of an application.
On top of those fundamental principles, in order to create a smart client we need to create a set of services that will expose them and allow our client to consume them remotely. This set of services corresponds to the services layer. Since those three layers are common to all types of smart clients, their creation won't be detailed in this article; instead this article extends the The Persistence, the Business, and the Service Layers one by using them in a Windows Presentation Foundation (WPF) application.
Preparing the WPF application development environment
At the very beginning of the The Persistence, the Business, and the Service Layers tutorial we created the Visual Studio project corresponding to our smart client: Sample.SmartClient.
First of all, we need to include the client configuration that CodeFluent generated, so that our smart client knows to which WCF services to connect to. To do so:
- Select the Sample.SmartClient project,
- Click on the View All Files button of the SolutionExplorer,
- Include the App.Config file in the project.
Furthermore, we now need to add the needed references to consume the WCF services exposed. To do so:
- Select the Sample.SmartClient project,
- Right-click on the project node, select Add New Reference...,
- In the new dialog, select the browse tab and select the CodeFluent.Runtime.dll assembly located in the CodeFluent installation folder,
- Add a reference to the .NET assembly WindowsBase,
- Add a project reference to the Sample.Proxy project.
At this point your Sample.SmartClient project should look like this:
Earlier in the tutorial, we configured the Sample project, so that the WCF services could be easily started and debugged. Now, we'll configure our solution so that on a debug action, it will launch: first the services, and then the client, so that we'll easily be able to debug the whole application. To do so:
- Select the Sample solution,
- Right-click and select Properties in the contextual menu,
- Right-click and select Properties in the contextual menu,
- In the Solution Property Pages dialog, select the Startup Project page,
- In the Startup Project page, check the Multiple startup projects,
- Set the Sample project as the first project to start,
- Set the Sample.SmartClient project as the second project to start,
- Click Apply.
This way, when we'll start debugging, Visual Studio will automatically launch our services, and then our smart client. Moreover, we'll be able to set breakpoints in both sides (client and server) or our application.
Now that our environment is properly configured, we can develop our User Interface (UI) that uses our CodeFluent generated components.
Developing the UI
The UI layer should only contain presentation code, all of the business logic should be in the Business Object Model (BOM). Hence, BOM objects are made to be data bound to, and provide advanced features to ease presentation layer developments such as validation capabilities, paging, sorting, caching, and so on. The Smart Client Object Model (SCOM) that we generated in the Sample.Proxy assembly is a remote version of the BOM containing the same capabilities (data binding, data validation, etc.) and taking care of all communication and transport matters. This way developers can truly focus on the UI and the business.
In this tutorial, we'll focus on a basic example that illustrates the data binding principle. We're going to create a WPF application which allows end-users to create and list customers. You'll see that thanks to the SCOM, practically no code behind is needed, and all communication matters are handled for us. Hence, the presentation layer will contain exclusively presentation code: this is a capital concern in order to create highly evolutive and maintainable applications. Thanks to this architecture, adding user interfaces is made easier, since only the "look & feel" is changed, we're not touching to any business logic in the presentation.
In the Window1 file, we'll create our user interface. Here's the XAML:
| Window1.xaml | Copy Code |
|---|---|
<Window x:Class="Sample.SmartClient.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Sample.SmartClient" Height="300" Width="500" ResizeMode="CanResizeWithGrip"> <Window.Resources> <DataTemplate x:Key="CustomerDataTemplate"> <StackPanel> <TextBlock Text="{Binding Path=Name}" FontWeight="Bold"/> <TextBlock Text="{Binding Path=Address}" Margin="5,0,0,0"/> </StackPanel> </DataTemplate> </Window.Resources> <Grid> <StackPanel> <GroupBox Header="Create a customer"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <StackPanel Grid.Column="0"> <Label Content="Name:"/> <TextBox Name="_customerNameTextBox" Margin="2,0,2,0"/> </StackPanel> <StackPanel Grid.Column="1"> <Label Content="Address:"/> <TextBox Name="_customerAddressTextBox" Margin="2,0,2,0"/> </StackPanel> <Button Grid.Column="2" Name="_createCustomerButton" Content="Create" VerticalAlignment="Bottom" Click="OnCreateCustomerButtonClick"/> </Grid> </GroupBox> <Button Name="_loadCustomerListButton" Content="Load Customer List" Margin="5,5,5,5" Click="OnLoadCustomerListButtonClick"/> <GroupBox Header="List customers"> <ListBox Name="_customerListBox" MinWidth="450" MinHeight="100" ItemTemplate="{StaticResource CustomerDataTemplate}"/> </GroupBox> </StackPanel> </Grid> </Window> |
|
Here's the code behind:
| Window1.xaml.cs | Copy Code |
|---|---|
public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void OnCreateCustomerButtonClick(object sender, RoutedEventArgs e) { Customer customer = new Customer(); customer.Name = _customerNameTextBox.Text; customer.Address = _customerAddressTextBox.Text; customer.Save(); } private void OnLoadCustomerListButtonClick(object sender, RoutedEventArgs e) { _customerListBox.ItemsSource = CustomerCollection.LoadAll(); } } |
|
Pressing F5 should launch a console application hosting the WCF services, and then your WPF application. Once the services are started, you can start using the WPF client. Create several users and then list them.
Here's what you should get: