Question

Having just gone through a small experimenting session to try to see how much work it would take to bring our .NET class library, or at least portions of it, into Silverlight so that we can reuse business logic between the two worlds, I'm wondering if others have experience with this sort of thing.

The things I noticed, off the top of my head:

  • Lots of attributes missing (Browsable(false) for instance)
  • Lots of interfaces missing, or present, but empty (ICloneable is hidden, ITypedList missing)
  • Reflection differences (everything reachable needs to be public)
  • Some base class differences (no Component?)

So I'm wondering, is it really feasible for me to even look at this as a possibility?

I got the initial code running, but I had to just comment out a whole lot of the base functionality, mostly around handling lists since they are based on ITypedList and some base classes. Apparently I need to change to ObservableCollection in Silverlight, so a whole of of base-code needs to be changed in order to cope.

The actual business test class I created is 99.5% identical to the one I would've made for .NET, only some minor changes that would easily be usable in .NET as well, just not as I would've made it before looking at Silverlight. In other words, it looks feasible to share business logic, provided I can make the base classes compatible.

Just so I'm clear, what I'm talking about is that I would basically have two project files, one for .NET, and one for Silverlight, but the actual C# source code would be the same, shared between the two.

So does anyone have any experience with this? Any tips or guidelines?

Will it be worth it? It certainly warrants more looking into.

Was it helpful?

Solution

It is definitely feasible.

It's done on a project here; the Silverlight project includes the C# ones, and there are some #IF statements handling some things (like log4net declarations), and other times things are just re-implemented. But in general, it's a huge win, and you should definitely attempt it (and certainly, we have, successfully).

-- Edit:

One point though, is that our OR/M (LLBLGen) didn't have inbuilt support for 'simple' objects to send down through Silverlight; but someone had written a plugin that handled it, which helped. So it may be worth considering what sort of DAL you're using, and how well it supports Silverlight.

OTHER TIPS

What I've done to facilitate this is:

  1. Frequent use of partial classes and #if !SILVERLIGHT to separate code into parts that Silverlight can handle.
  2. Use of code generation whenever possible. For example I've been experimenting with T4 templates that generate Silverlight equivalent attributes (DisplayAttribute instead of DescriptionAttribute for example)
  3. Whenever there's an interface/attribute that isn't implemented by Silverlight (such as IDeserializationCallback, ICloneable, INotifyPropertyChanging) I will create a dummy interface of the same name in the Silverlight application as long as I know that the fact that the implementation won't be used is not a problem.
  4. Finally, it's worth noting that in Silverlight 4, the assembly format does allow for sharing of binaries between Silverlight and .NET as long as there are no dependencies that Silverlight does not support.

One more note about the separate base classes - it may be worthwhile to create an abstract class that derives from ObservableCollection in Silverlight and BindingList (or whatever you're using in .NET) to minimize the impact on your typed collections.

UPDATE Today I was working on porting some .NET code to Silverlight that made heavy use of the System.Diagnostics API's like TraceSource, SourceSwitch, etc which do not exist in Silverlight. I created very minimal implementations of these in the Silverlight project and put them in the Einstein.Diagnostics namespace. In doing so I decided I needed a convention to easily identify code that was mimicking the .NET Framework vs. my own code. So I renamed the placeholder files to prefix them with an @ sign. I also prefixed the class names in those files as well. The nice thing about that is that the @ sign does not actually change their class names as far as the C# compiler is concerned. So @SourceSwitch still compiles to be Einstein.Diagnostics.SourceSwitch but in the code I can easily see something is up. I've also decorated these classes with a [SilverlightPlaceholder] attribute.

I do this with protobuf-net, and I use a few approaches:

  • conditional compilation symbols in the project file to trigger subtle code-branches (yes, it isn't perfect, but it works)
  • re-introduction of some things; attributes might be an example here - your code can still use re-introduced attributes, even if the framework code doesn't; as a more extreme example of this, for compact framework I had to re-introduce a good chunk of the Expression API, which was fun
  • just drop some things ;-p

However if you are using ITypedList (which you mention), I can see that whole approach falling apart pretty messily; component-model is complex enough already, without having to force your way through the hacks too. It really depends quite how far you've gone down this road. Maybe 4.0 / dynamic will open up some of these options again?

One possible fix to your issue is to copy the missing code from the Mono project. Back in the day, I did a small project with the Compact Framework and it was missing the entire System.XLM namespace. I just copied the entire thing from Mono into my project, compiled it and it worked great with minimal changes, iirc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top