Siverlight Architecture Feedback (Part 1/2)

Thanks to Devoteam Luxembourg, i am actually setting up a Silverlight architecture but it was not my first practice… I have already setup Silverlight architectures over a service layer. In most cases, i found some great shortcuts, some tips about what can be done and what can”t be done. My brainstorm result will be explained in this paper.

Uses cases

Since few years, I am practicing Silverlight in a business context. In each cases clients ask us to develop a user interface with business logic and persistency. Most of time, clients wanted a CRUD application with a nice user interface.

 

Target

Theses software had to manage complex data and, for each data type, must:

  • Have a read only view,
  • Have a write view,
  • Manage complex properties/navigation properties by adding or removing sub items,
  • Have a corporate view and an innovative user experience,

 

I have proposed approximately the same architecture, even with my experience feedback… Silverlight over SOA was for me the solution by design for many requirements.

  • Multi-User
  • Less deployment problems
  • Expose services/resources for others
Global architecture Silverlight

Simplified architecture

 

Sample of my last project packages

Detailed package diagram

The (L) icon says that files are “add as link” under the project. In this case, changing it in the first and real reference says that you change it where the file is linked.

Tools & Technologies

Through NuGet, I am using MVVM Light, Entity Framework 4 and also T4 code generation from Microsoft with a T4 editor.

In details

 

From database to classes

From database to classes

Based upon the database, I create an EDMX file that generate the persistency layer and the POCO files. This POCO files embed all the entity framework persistence layer. Also based upon the EDMX file, a T4 file can generate the DTO in MVVM Light format and the AutoMapper configuration.

The T4 generator is a fork of the Self Tracking Entity version. It generates one file per class for the DTO and one global file that define the AutoMapper’s configuration.

In this configuration, changing the data format or the data source allow developer to be more reactive. They have to adjust web services and views.

DTO choice allow developer to extend the generated pack by custom DTOs. For example in auto-completion features.

The generated MVVM DTO

This file will contain one MVVM property for each corresponding property in the given class (with RaisePropertyChange call for example).

The generated AutoMapper configuration

It will generate the configuration from POCO to DTO (full copy) and from DTO to POCO preventing copy of primary key, complex and navigation properties.

The data transfer

 

Data migration through layers

Data migration/conversion through layers

We will now describe how the data will evolve in the architecture.

The data is actually stored in the database. Through a LinQ request, the business layer will find the data and Entity Framework will fill a POCO. By default, the lazy loading is disabled. It will prevent loading the entire database with AutoMapper or serialization. User must say which data is needed. Once the POCO filled, AutoMapper can transfer data from it to a new DTO before sending it through WCF.

Silverlight will receive data and can directly bind it on views.

On the other way, Silverlight can modify the principal data and send it back to the server. Business layer will receive a DTO. If it already exists, load it and write over thanks to AutoMapper. If it doesn’t exist, it will add data to the persistency layer.

Helped with a static method, it is possible to “merge lists” for hierarchical entities. You can find the script below and discover the target of the function. This is inspired from the stackoverflow thread solution exposed here.

public static void Reconcile(EntityCollection databaseList,
                                           ObservableCollection dtoList,
                                           Func keySelector,
                                           Func keySelectorDTO,
                                           Func databaseFinder) where T : class where TDTO : class
        {
            Dictionary databaseDict = databaseList.ToDictionary(key => keySelector(key));

            foreach (TDTO dtoObj in dtoList)
            {
                int key = keySelectorDTO(dtoObj);
                T databaseObj = null;

                if (databaseDict.TryGetValue(key, out databaseObj))
                {
                    databaseDict.Remove(key);
                }
                else
                {
                    T databaseObjFound = databaseFinder(key);
                    if (databaseObjFound != null)
                    {
                        databaseList.Add(databaseObjFound);
                    }
                }
            }

            foreach (T removed in databaseDict.Values)
            {
                databaseList.Remove(removed);
            }
        }

 

Validation

Validation can be setup by creating a partial class and adding the validation helped with FluentValidation. You can setup validation server side and add a link of the partial class client side. With this configuration, you can add client side only, server side only or both if you want.

The validation details can be found here

 

Leave a Reply

Your email address will not be published. Required fields are marked *