Silverlight Line Of Business Applications With Offline WPF Versions

Here are my top 10 thoughts on building line of business applications deployed both as a Silverlight and a WPF application.

1.  Silverlight assemblies cannot reference standard .NET assemblies.
   
    You'll notice in Visual Studio that Silverlight has its own project types.  These project types also have restrictions as to which framework
    assemblies are available to it.

    If you are building components to be deployed with a Silverlight application and some other .NET application such as WCF or WPF, I
    suggest creating a single folder with both the standard .NET project file and the Silverlight project file stored in it.  Then, you can simply
    include the .cs files (or other applicable file types) in each project.

    I like to append the .Silverlight naming convention to Silverlight projects.  Makes it even easier to keep track of your project files.  Also,
    remember to change the default namespace in your Silverlight project to match that of your standard .NET project.  You'll want to use
    the same namespaces in both project types.

2.  Not all classes, properties, and methods behave the exact same way  between Silverlight and WPF.

    You will run into situations where the same class file has methods or properties that have different parameter options or behave
    differently in a Silverlight application versus a WPF application.  It doesn't happen often but will occur.  I've seen it occur with the
    BitMapImage class and some conversion methods regarding UTF encoding.

    By using the two projects in one folder option mentioned in #1, you can usually get around this by creating a folder for Silverlight specific
    class file workarounds.  This permits you to include your normal class file in a normal .NET project and the Silverlight workaround file in
    your Silverlight project.  If you use the same namespace and class names, the rest of the application will never know the difference.  Of
    course, this technique should be used as a last resort.  

3.  The System.Data assembly is not available for use in Silverlight.

    The Entity Framework 1.0 requires some of your classes to be decorated with attributes that exist in the System.Data
    namespace.  This virtually excludes using the Entity Framework with Silverlight applications if you intend to use the
    exact same class in WCF that you do in your Silverlight application.

4.  XAML in WPF does not necessarily equate to XAML in Silverlight.

    If you are writing an online version of your application in Silverlight and an offline version in WPF, write your Silverlight
    application first.  Most of the time, any XAML written in Silverlight will work in WPF.

5.  Today's Silverlight application is likely to be tomorrow's offline version in WPF.

    It is this statement alone that should give you great pause when attempting to create a religiously pure service
    oriented architecture between your Silverlight and WCF application.

    If you were to construct an offline version of your application in WPF, many of the design decisions you would make
    will likely have different outcomes.  There is no longer a network oriented service which forms a natural barrier between
    what the client application can use directly and is thus dependent upon the server side to deliver. 

    Your only real choice is to create shared data contracts with the same namespaces across the WCF, WPF, and
    Silverlight applications.  Failure to do so will create circular reference and ambiguous namespace issues all over the
    place.  When this occurs, the only option is to manage different sets of code that perform the same task.  Ugh...

    I like to make environment aware business logic assemblies which disconnect all logic from classes that could be
    transferred to other environments across the WCF, Silverlight, and WPF spectrums.

    Then, I prefer to create a shared environment interface to these business logic classes used in the Silverlight and WPF
    applications.  The WCF application could reference the offline business logic class directly if you chose to bypass the
    use of the interface.

    This technique enables shared user interface components to use the same business logic interface.  The business logic
    underneath the interface either uses code for connecting to WCF or code connecting directly to the database in an
    offline local database environment.

    I tend to keep a separate user interface logic assembly from my WPF and Silverlight projects.  This enables a single
    code set to manage user interface logic that can be reused in both environments.  What we are left with is just the
    XAML and top level events in the WPF and Silverlight user interface assemblies.  Towards the end of the application
    development cycle, you will likely be able to move some of your XAML files into the shared user interface logic
    assembly to avoid code duplication.

    The process flow ends up looking like this:


     WPF                                                                                             Silverlight
    
                                                        Shared UI
                                               Business Logic Interface

     WPF Business Logic                                                            Silverlight Business Logic
     WPF DataBase                                                                                WCF
                                                                                                   WPF Business Logic
                                                                                                      WPF DataBase


6.  A WCF reference in a Silverlight or WPF application is just a set of generated source code.

    The proxy classes created are not biblical written text creations or laws governing SOA.  They are just
    code automatically spit out for you.

    The Visual Studio service reference creator now offers advanced options which include collection types and
    namespace reuse between your WCF, Silverlight, and WPF assemblies in the software family.  When creating
    online and offline versions of the same application, use this feature.  It is a godsend.

    * Nhibernate does not yet support ObservableCollection.  Beware of this when deciding which collection type to standardize on.

7.  Silverlight requires an asynchronous programming model.

    You may not like it but you need to accept it.  I'll spare you the details you can read elsewhere about Silverlight's
    use of the browser network stack.  What is important for you to consider is the impact this has on your offline WPF
    application.  If you are smart, you'll wire up your offline business logic to handle both asynchronous and synchronous
    methods.  Then, just expose the asynchronous methods via your business logic interface.  This avoids confusion by
    your user interface developers working in Silverlight and WPF but still permits your WCF layer to reuse the WPF
    business logic class and call the synchronous methods.

    One additional suggestion (and admittedly an odd one).  For insert/update/delete oriented web methods, I've found it
    quite beneficial to make the passed in class also the return value (ex.  public Customer DeleteCustomer(Customer record)). 

    The asynchronous nature of Silverlight calls to WCF means you've lost the reference to the record you were working
    with when the asynchronous complete event fires.  By returning the class you sent in, that same class reference ends
    up in the .Result property.  You could then use properties on your class to populate status messages or fire some other
    method with it as a parameter.

8.  Silverlight does not support WCF FaultExceptions.

    You'll need to send in a custom exception object as an out parameter to all of your WCF web methods/entry points.
    Populate it accordingly in the WCF method and it will show itself in the Silverlight in the MethodCompleted oriented
    event from the asynchronous call to WCF.  It appears as a property on the result class passed into the event.
    I tend to put success or failure properties on the custom exception class to provide a standard way to react to
    failures when the asynchronous complete event fires.

    You will also need to standardize on methods for passing custom exceptions back up through the user interface
    layer in WPF and Silverlight.  Remember, Silverlight is reacting to return values from WCF and WPF is most often
    times reacting to direct database calls.  Any shared user interface components will expect the same behavior of events
    from both business logic types.

9.  WCF does not permit the DataContract or DataMember attributes on .NET interfaces.

    Returning ICustomer instead of Customer from a WCF method results in the use of object instead of a
    strongly typed Customer class.  You may want to consider using an abstract pattern with Customer if you
    want to create other variations of a Customer interface.

10. I was correct. 

    Building online/offline versions of line of business applications in Silverlight and WPF is a complicated task.
    However, it is doable if you think very carefully about component reuse and reduction of code duplication up front.
    You will also need to think outside the box and perhaps vary from some of your normal design techniques.  It
    doesn't make your old design techniques wrong.  It just may mean that they are not a good fit for this type of
    application and could create obstacles you cannot overcome.


By Robbe Morris   Popularity  (2885 Views)
Picture
Biography - Robbe Morris
Robbe has been a Microsoft MVP in C# since 2004. He is also the co-founder of NullSkull.com which provides .NET articles, book reviews, software reviews, and software download and purchase advice.  Robbe also loves to scuba dive and go deep sea fishing in the Florida Keys or off the coast of Daytona Beach. Microsoft MVP