Click here to Skip to main content
Click here to Skip to main content

Four Simple Steps: Creating a Silverlight Business Application Using DevForce

By , 25 Mar 2009

Editorial Note

This article is in the Product Showcase section for our sponsors at CodeProject. These reviews are intended to provide you with information on products and services that we consider useful and of value to developers.

DevForce has been designed from the ground up by experienced enterprise application developers with several very important goals in mind:

  • Make it (following Albert Einstein’s famous advice) “as simple as possible, but not simpler.”
  • Support (and encourage) “separation of concerns” in the architecture: your business model (and all business logic) is entirely separate from your user interface, so you can reuse it across more than one user interface, and more than one application.
  • “Don’t fence me in.” You build the application you want to build, with the functionality and user interface you need. We make that much easier for you, and we make sure your end product is truly industrial strength -- but we don’t take over, and we don’t get in your way. Not in the beginning, and – even more importantly – not later on, after you’ve invested so much into your development effort that changing course is no longer an option.

    So what’s it like to build an application with DevForce Silverlight? Let’s take a walk through the four simple steps:

  • Generate your Silverlight and web projects using the DevForce Silverlight project template
  • Create your Entity Data Model
  • Create your DevForce Domain Model
  • Create your UI.

Download DevForce

Step1. Generate Your Silverlight and Web Projects

DevForce provides a Visual Studio project template to get off the ground quickly with your application. Choose File / New / Project from the main menu, find the DevForce section under the language of your choice, and select the DevForce Silverlight Application project template.

Specify the name and storage location for your new solution, and click <OK>:

The template creates two projects. The web project (here named DevForceSilverlightAppWeb) will ultimately be deployed on your IIS server; the Silverlight project (DevForceSilverlightApp) will contain the application parts that will be downloaded automatically to the client’s browser via a .XAP file.

Note that the web project is set as the Startup Project for the solution. That’s important! If the Silverlight app is set as startup, the MainPage will still display, but all operations that require connection to the server – like login and data retrieval – will be dead in the water!

That’s it for step one. We have our application structure, and needed references to DevForce and .NET assemblies are already set. Let’s get on with creating our application’s business model!

Step2. Create your Entity Data Model

The ADO.NET Entity Data Model is used only server-side in our DevForce Silverlight application, so let’s add it to the web project:

Please note that adding the Entity Data Model to the web project isn’t your only option: you may prefer to give it a project of its own. The only requirement is that it should ultimately reside in an assembly that is deployed server-side.

Download DevForce

We’ll name to indicate its function in the app, and the database to which it will map:

We’ll generate the app from a database…

… name our connection settings...

…select the tables we want mapped…

…and click <Finish>. The wizard cranks out the Entity Data Model, which looks like the following:

There are a few naming problems with the model as generated by the EDM wizard. For one, it’s impossible to distinguish a navigation property that returns a collection from one that returns a single related object. The Order property that appears on both the Customer and Employee entities returns, in each case, a collection of Orders. So does OrderDetail in the Order type. But Customer and Employee in the Order type return single objects, not collections. It would be helpful if the pluralization of the names reflected the actual content of the properties.

Also, if we inspect the Properties for any of the entities defined in our model, we’d see that the name of the Entity Set that will hold instances of that entity is the same as the name of the type itself: again, not so helpful, as we might well prefer that the set names be plural and only the type name singular.

We could clean those things up using the EDM designer, but as it so happens, it’s quite a bit easier to do in the DevForce Object Mapper, so we’ll defer that cleanup and proceed straight to step three.

Step3. Create your DevForce Domain Model

Now that we have an Entity Data Model, we’re ready to create our DevForce-generated Domain Model. Before we do that, though, let’s take a few moments to answer a couple of basic questions:

  • Why two models? and
  • What do I get in a DevForce Silverlight app that I wouldn’t get in any Silverlight app?

The ADO.NET Entity Data Model provided by Microsoft provides a great structure for mapping objects to a relational database, and as used by the Microsoft Entity Framework, permits you, the developer, to completely offload the work of writing data access code. Not only do you no longer need to master the various dialects of SQL supported by different DBMS vendors: you no longer need to write SQL in any form. In your application code, you talk to an object model that can be designed to fit your application like a glove. You are buffered from the design details of the back-end database, which may be at once a poor fit to your application and also difficult or impossible to change.

Unfortunately the Entity Data Model can’t be used in a Silverlight application, because there’s nothing in Silverlight that knows how to do anything useful with it. (The Entity Framework isn’t part of Silverlight.)

Darn!

But wait…DevForce to the rescue!

DevForce leverages the power and benefits of the Entity Data Model and the Entity Framework on the application server, but gives you a model and a surrounding apparatus that can be used, in very powerful ways, within your Silverlight client. DevForce includes an EntityManager, similar in function to the Entity Framework’s ObjectContext, but much more powerful. This EntityManager resides client-side and maintains a business object cache that you can query using LINQ!

But the DevForce-generated DomainModel will also be used server-side. DevForce uses the model server-side and client-side in ways that are appropriate to the two different environments. You have one business model to maintain – not two.

The figure below shows how DevForce enables you to leverage the power of the Entity Framework in your Silverlight application. The Devforce Entity Manager maintains a queryable client-side cache of business objects retrieved from the back-end data store(s).

DevForce-enabled LINQ queries can be directed against the client-side cache or against back-end data stores.

When directed against the data store, they are automatically translated by the DevForce Entity Server into LINQ-to-Entities queries that the Entity Framework can process. The Entity Framework then generates the necessary SQL to retrieve the data from the database, which it delivers to the DevForce Entity Server. The Entity Server very efficiently ships the data to the client where it is converted into DevForce business objects of the types defined in your DevForce Domain Model.

Crossflow of Data and Business Objects.png

Note, by the way, that unlike the Entity Data Model, the DevForce Domain Model doesn’t limit you to using a single database as a data source. The DevForce Domain Model can encompass any number of Entity Data Models, each mapping to a different relational database. Even further, it can use DevForce-generated Entity Data Models that are based on web services – something entirely beyond the standard Entity Data Model’s capabilities!

Our Entity Data Model(s) will get a few automated modifications from DevForce, but will otherwise remain as generated. Their purpose will be to link the DomainModel against which you write all of your application code to the powerful data retrieval and storage capabilities of the Microsoft Entity Framework.

Okay, enough with the background. Let’s see just how easy it is to create our DevForce DomainModel.

Start by launching the DevForce Object Mapper from the Tools menu in Visual Studio:

The Object Mapper launches. By pulling down the Model menu or right-clicking the (New Model) node in the left panel, we can begin the process of linking our Domain Model to an existing Entity Data Model:

Since we have only a single Entity Data Model in our solution, the Object Mapper automatically finds it. You have only to confirm that this is an Entity Data Model you’d like to include in your Domain Model by clicking the <Open> button.

The Object Mapper will quickly mine the EDM for information and then display its structure.

Download DevForce

By selecting the ServerModelNorthwindIBContext node in the tree, you can see (and edit) much more of the detail about the EDM.

We’ll drill into the Order type and change the name of the Freight property (based on a Freight column in the Order table in the NorthwindIB database) to FreightCost.

Similarly, we’ll change the Navigation Property named Employee to “SalesRep” to reflect the Employee’s actual role with respect to an Order:

The navigation properties Employee1 and Employee2 (on the Employee type) were generated because the EDM wizard found a self-referencing relationship on the Employee table. That relationship reflects the recursive hierarchy among Employees: any Employee reports to a single manager, but can be the manager for many other Employees. The EDM wizard did the best it could naming the needed navigation properties...

... but we’d really like to do better. Problem is, we can’t easily tell which one of the navigation properties will return the current Employee’s single manager, and which will return the collection of her direct reports.

We’ve got other annoying little naming problems in our model. If you re-examine one of the earlier screenshots you can see that entity sets are named the same as entity types:

We’d really like to distinguish the set names from the name of the types they contain. We could do it one at a time, but the Object Mapper has a handy little tool to fix all of our pluralization-related problems at a single stroke: the Name Pluralizer on the detail screen for the .edmx node:

We’ll just accept the default settings and click <OK>.

The Entity Sets now have plural names...

…and so do the navigation properties that return collections.

Now it’s easy to see how to change our navigation properties for the management hierarchy:

=>

There are many other settings we can change in the Object Mapper, but let’s say we decide we’ve done enough to generate our model code and get started with other aspects of our development process. (We can always come back to the Object Mapper for further work.)

We select the Domain Model node in the model tree:

If we accept the default locations suggested by the Object Mapper, and indicate that we want to “Create developer partial class files” with the CheckBox so labelled, we’ll end up with a solution that looks like the following:

The Object Mapper generated a code file:

DevForceSilverlightAppWeb.ServerModelNorthwindIB.Designer.cs

into the web project, along with code files for each of the types in the Domain Model (Customer, Employee, Order, etc.). It also placed a linked copy of the same code files into the Silverlight project, so that the same code will be compiled into the Silverlight assembly created from that project.

There is a great deal more you can do in the Object Mapper: defining and assigning base types, allowing or disallowing nulls, enforcing column widths on strings, setting up facilities for diagnosing concurrency conflicts, and so forth. But your model doesn’t have to get any more complicated than you need it to be, and you can introduce detail incrementally. The Object Mapper round trips, so you can return to it throughout your application development cycle to add, remove, or modify your objects.

You’ll almost certainly want to add custom business logic to your developer partial class (housed in those Customer.cs, Employee.cs, and Order.cs files) including custom properties and methods, property interceptors, validation logic (using DevForce’s very robust Verification features), security logic, event handlers, and the like. But our model is ready now for sophisticated data retrieval and storage, so let’s slap on a UI and let ‘er rip.

Download DevForce

Step4. Create Your User Interface in the Configured Silverlight Project

Actually, we already have a UI of sorts. Our Silverlight project got generated with a XAML MainPage (and associated “code behind” file) that is set as the application’s start page. We can, in fact, run the application right now. If we do, we’ll see this:

It’s comforting to see that our application already runs, but let’s put something together that uses those powerful data persistence facilities! We’ll add a TabControl to MainForm (just to create future expansion possibilities), and give it one TabItem. Into that TabItem we’ll add a custom UserControl named DynamicGridEditor.

When we run the app it looks like this:

The DynamicGridEditor uses a Silverlight 3 DataGrid to display a list of the entities that satisfy a query selected by the end user from the ComboBox labelled “Query:”. The detail for the selected grid item is displayed in a Silverlight 3 DataForm. The Query ComboBox actually lets you pick queries that return several different types:

This is all done with remarkably little code! If you download the Visual Studio solution on which this article is based, you’ll see that adding additional queries that return other types is just a matter of writing the query and tossing it into a dictionary defined in the DynamicGridEditor’s “code behind”. The DataGrid and the DataForm adapt automatically!

Here’s the complete XAML for the MainForm:

<UserControl x:Class="DevForceSilverlightApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:slControls=
        "clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    xmlns:local="clr-namespace:DevForceSilverlightApp" 
    Width="Auto" Height="Auto">
    <Grid x:Name="LayoutRoot" Background="White" >
        <slControls:TabControl x:Name="_mainTabControl">
            <slControls:TabItem x:Name="_dynamicGridEditorTab"
                Header="Dynamic Grid Editor">
                <local:DynamicGridEditor />
            </slControls:TabItem>
        </slControls:TabControl>
    </Grid>
</UserControl>

This is what the DynamicGridEditor looks like in the designer…

…and here’s the central part of its XAML:

    <StackPanel Grid.Row="0" Orientation="Horizontal" Margin="10,10" >
      <Button x:Name="_loginButton" Click="LoginButton_Click" 
         Style="{StaticResource button}" Content="Login" />
      <Button x:Name="_saveButton" Click="SaveButton_Click" 
         Style="{StaticResource button}" Content="Save" />
    </StackPanel>

    <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="10,0" >
      <TextBlock>Query:</TextBlock>
      <ComboBox x:Name="_queryCombo" Margin="6,0" MinWidth="30"/>
      <TextBlock Margin="20,0,6,0" x:Name="_queryAsString" Foreground="Blue" />
    </StackPanel>

    <dataControls:DataGrid x:Name="_dataGrid" Grid.Row="2" 
      Margin="10,10" Style="{StaticResource grid}" 
      AutoGenerateColumns="True" HeadersVisibility="Column"
      SelectionChanged="DataGrid_SelectionChanged"
    />

    <Border Grid.Row="3" BorderThickness="1" Margin="10,0" BorderBrush="Gray">
      <dataformControls:DataForm x:Name="_dataForm"  Grid.Row="3" 
         Margin="10,10" CanUserAddItems="False" CanUserDeleteItems="False" 
         AutoGenerateFields="True" />
    </Border>

Note the AutoGenerateColumns and AutoGenerateFields settings in the DataGrid and DataForm controls, respectively. When coupled with our previous instruction to the Object Mapper to “Generate Binding Attributes”…

…these cause the controls to pick just the right set of properties from the bound objects to display!

There’s no custom “code behind” in MainPage, and a surprisingly small amount in the DynamicGridEditor. Here’s the code that defines the queries and initializes the Query ComboBox:

    #region InitializeQueries

    private void InitializeQueries() {
      _queries = new Dictionary<string, EntityQuery>();

      _queries.Add("{None}", null);

      _queries.Add("Get all Customers", _entityManager.Customers);

      _queries.Add("Get Customers starting with 'A'",
                  _entityManager.Customers
                    .Where(c => c.CompanyName.StartsWith("A")));

      …[snip]…

      InitializeQueryCombo();
    }

    private void InitializeQueryCombo() {
      var qNames = _queries.Keys.ToList();
      _queryCombo.ItemsSource = qNames;
      _queryCombo.SelectedItem = qNames.FirstOrDefault();
      _queryCombo.SelectionChanged += delegate { Fetch(); };
    }

    #endregion

When the selected query is executed, its results are simply placed into a list which is then assigned to the ItemsSource property of the DataGrid. Finally, the DataForm’s ItemsSource is set to the ItemSource of the DataGrid. That ensures that the data displayed in the two controls will be synchronized.

To see more, we encourage you to download the Visual Studio solution on which this article is based and put it through its paces. You’ll be amazed at the power in this tiny, quickly built solution!

Download DevForce

Conclusion

So there you have it: an n-tier Silverlight application in four simple steps. With DevForce and Silverlight, you can now build data-intensive Rich Internet Applications with a great user experience and seamless deployment. By freeing you from the task of writing and maintaining the extensive plumbing and infrastructure code necessary to support an n-tier model, DevForce allows you to focus on building the application you and your customers need and want.

DevForce ships with plenty of documentation, code samples, and tutorials to help you address the full spectrum of development tasks; and a world-class team of engineers will help you over the rough spots. Try it today!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

IdeaBlade, Inc.

United States United States
No Biography provided

Comments and Discussions

 
QuestionGenerate Database from Classes Pinmembergeorani31-Mar-09 0:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140415.2 | Last Updated 25 Mar 2009
Article Copyright 2009 by IdeaBlade, Inc.
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid