One of the first things that came to mind when I heard that silverlight was going to be adding managed code support, was the potential to reuse code between the server and the client. I had been successfully following this methodology for my compact framework development, and now it was possible for silverlight web applications as well! [Insert happy dance here]
One of the main areas I like to reuse code has to do with the object model, and the validation thereof. Just as a reference, when I say "object model", I mean dumb data carriers for my entities. ie: Classes that contain only properties, not behavioural methods. Not that you can't add methods to your OM classes, I just prefer to keep them simple, and let other classes take care of behaviour / validation etc.
Okay - enough blog waffle, let's get straight into sharing your code between server and client!
Here's a picture of a typical basic silverlight architecture:
The idea is to share code between the .NET application layer and the silverlight client layer, and even allowing the classes for the shared code to be serialized over the wire.
NOTE: For the last bit (code sharing that involve "over-the-wire" serialization), you'll need to wait for the release of Silverlight 2 RTW . I can confirm that RTW release does allow the re-use of types in referenced assemblies. :)
Step 1: Define the code
Typically, there are 2 strategies for defining the canonical source of the code: 1) Place it in a shared location, and link it to projects that need it, or 2) Define it in the project with least namespace dependencies, and link it up to other projects.
If you're sharing code across the compact framework, silverlight, and the full .NET framework, I recommend 1), but if you only plan on using the code for one of the subset frameworks, I recommend 2), which is the one I'll describe in detail here.
The reason for defining the class in the silverlight class library is purely due to maintenance reasons. When modifying the source code, always modify it at it's source. That way you know you're not adding any code that depends on framework namespaces that do not exist.
eg: If I open the class where it is defined in the silverlight class library, and try and add a DataSet property, the designer will immediately tell me that this is not possible. If the class was defined in the server assembly, I would only find the dependency error at compile time when the client assembly compiles.
One final note on the class definition: It may be helpful to mark your classes with the "partial" keyword, as you may wish to extend the defined class into server and client specific implementations. That, or you could define new client and server types which inherit from the shared base implementation - whichever makes more sense in the underlying design.
Step 2: Link the Code to the Server Assembly
The idea is that there is only one version of the code on disk, otherwise it's just code duplication, and not code sharing / reuse.
To reuse the code defined in Step 1 in your server class library, do the following:
From the server assembly project menu, select "Add Existing Item", and navigate to the class file defined in Step 1. Instead of clicking the Add button (which would just duplicate the code) select the arrow next to the add button, and select "Add As Link"
You will notice that there is a little shortcut mark on the class icon in the solution explorer. This indicates that the file is declared elsewhere (your silverlight assembly in this case).
ie: Whenever you make changes to the class definition, it will automatically be reflected in all the places where the source code file is linked.
NOTE: Be careful not to open the file from the shortcut, as Visual Studio will open it assuming you are in the current project, and you will have access to all the .NET namespaces. ALWAYS edit the code by opening it from the canonical source.
Step 3: Share the Code Over WCF Services
If your code is going to be "traversing the wire", then mark it with the usual [DataContract] and [DataMember] attributes. (NOTE: Since the release of SP1, you don't need to explicitly mark your data members - only do so if you want to explicitly exclude certain properties from serialization. ) Make sure that System.Runtime.Serialization is referenced in all projects making use of the shared code file.
From the Silverlight client project, right click and select "Add Service Reference". Add a reference to the WCF service you would like to consume, making sure that the checkbox "reuse types in referenced assemblies" is checked in the advanced options (as displayed below).
When reusing types (which will only be available from silverlight 2 RTW), the svcutil, which is used to generate the client proxy class definitions for the DataContracts, will add references to the client versions of the code (the class created in Step 1) instead of generating them in the Reference.cs file of the service.
...And that's it - now you're sharing C# code between server and client.
I'm currently finding this very handy for executing common business rules on object classes on the client in order to prevent unnecessary round tripping to the server.
It's also become very handy for generic framework implementations using the common base classes. Also, If you have the same DataContract defined in two separate services, instead of them being defined twice (once for each service reference), both services reference the existing client-side class, allowing the generic code implementation mentioned above.
I'm working on posting some (simple) sample source code - watch this space.