Mocking and IOC in Silverlight 2, Castle Project and Moq ports

Some time ago I started wondering about mocking and IOC in Silverlight 2. There is quite obviously a gap here that someone needs to plug, as soon as you start writing tests (thank you Jamie Cansdale!) you're going to need mocks of some sort and as soon as you have a Silverlight project of any real size, IOC becomes necessary.

Mark Monster blogged about what it would take to port Castle DynamicProxy and consequently Moq to Silverlight and so until someone comes along with a better or official solution I decided to take up the challenge. There was a fair amount of work, although in terms of actual code changes that were needed due to API changes in the Silverlight CLR there was really very little, the brunt of the work as Mark pointed out was around the lack of Remoting and also the lack of non-generic collections in Silverlight. I will just note though Mark, your list of code changes required to get these projects to compile is a MASSIVE underestimate, because the compiler shows as many errors as it can, but only when you fix these does it throw another few hundred at you!

There was a lot of code in the Castle libraries to support remoting and serialization for remoting (MarshalByRefObject, ISerializable, IDeserializationCallback, SerializableAttribute etc etc), none of this is actually required for any of the core features and aren't supported in Silverlight and so I ripped it all out! The other big chunk of work was that there were hundreds upon hundreds of references to types which are missing in Silverlight 2, generally it was non-generic collections such as ArrayList and Hashtable, but also there were some key threading classes which were absent. I solved this by creating a new assembly called FlawlessCode.MissingTypes and adding into this implementations for the missing types. No, I didn't write them all! What I did do was download the Mono source code and use their implementations! You may notice I changed the namespace of all the Mono types to start with FlawlessCode and not System, this is because some of these collections are implemented internally in the Silverlight CLR but just aren't exposed for our use and Visual Studio was complaining to me.

There were some other changes required in the Castle libraries for features which would make no sense and could never work on Silverlight, these of course were removed. Castle DynamicProxy has the ability to save generated assemblies to disk for example, and Castle Core has types like FileResource and UncResource. None of these will ever work in the way intended because Silverlight doesn't have proper access to the file system.

Moq by comparison was very very easy to port, the only real problem was the HastSet<T> class which is not available, thanks go out again to Mono for this!

In terms of IOC, I also ported the Castle MicroKernel. This should give you the basics to play around with, but I have NOT ported Castle Windsor, the reason being that there is a lot of Xml handling code contained therein and it uses XmlNode, XmlElement, XmlDocument etc... this would all need changing to XNode, XElement, XDocument and the like, to be honest I was tired and thought I'd done enough!

To cut a long story short, all the unit tests now pass! I just want to thank the people who made all this possible in the first place, Jamie Cansdale for the Silverlight NUnit work, the people behind the excellent Castle Project, the people behind Moq and of course the Mono Project. I want to be clear that I'm posting this here as a stopgap solution so that all the people working with the beta of Silverlight 2 have something to play with and to perhaps show that this is possible, but really I'm hoping this will be worthless very soon and that someone who really knows what they're doing does a real port or that we get official support from Moq and Castle.

One issue I do know about with all this, Assembly.GetName which is used by DynamicProxy is marked as SecurityCritical, and as such stops the whole thing from working at all! This would be a disaster and indeed if you were wanting to run Moq or DynamicProxy in the browser it is a disaster, however the way in which Jamie got NUnit to work was by making Visual Studio load the silverlight DLLs using the desktop CLR, and apparently when doing this, the desktop CLR takes no notice of SecurityCritical. The end result is that DynamicProxy works fine using Jamie's unit test templates, but if you reference DynamicProxy from your silverlight app and expect it to run in the browser, it won't.

DISCLAIMER: For what it's worth, I'm not a legal mind and while I don't think I'm doing anything wrong by mashing together all this different open source code, if I'm violating anyone's licenses please give me a heads up before you unleash the hounds and I will of course pull it down immediately.

DISCLAIMER 2: While this all seems to work so far and the unit tests do all pass, I did monkey around with the code quite a bit, so please take this as it comes and don't expect too much!

Download

Castle-SLandMoq-SL.zip (770.03 kb)

kick it on DotNetKicks.com

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList
August 15, 2008 08:46 by Sean
E-mail | Permalink | Comments (6) | Comment RSSRSS comment feed

Related posts

Comments

August 17. 2008 17:52

Hi Sean,

If you have not already done so, you might check out the following:

SLUnity
michaelsync.net/.../unity-for-silverlight-two-samples-and-test-projects-are-on-codeplex-now

Silverlight.FX
http://www.nikhilk.net/

best regards,
David Roh

David Roh

August 17. 2008 18:06

Good work Sean. Sad to see I underestimated the work to be done. I did kind of a dry analysis but this is better of course. Maybe this can be a start for specially the people behind the Castle project to leverage a Silverlight version of their DynamicProxy.

Excellent work, I will try it soon!

Mark Monster

August 18. 2008 12:01

I can only say: wow!

Ruurd Boeke

August 19. 2008 07:34

@David: Thanks for the heads up, I hadn't seen SLUnity I'm going to download and play. I just also found Ninject (http://ninject.org/), which aparently officially supports SL2! Oh well, been a great learning experience to have a good poke around inside Castle..
I did see Silverlight.FX and it pretty much blew me away, stunning work, although my transitions post was from way back in March ;)


@Mark: I do hope they come through also, I think the Assembly.GetName thing though is going to be a sticking point for working with strong names.

@Ruurd: Thanks man!

Sean

August 26. 2008 20:01

Sweet. Awesome work man! way to go!

Now, contact the owners of those frameworks, get their permissions and distribute this on codeplex.
(Seriously, it took me 10 minutes of reading just to understand you DID manage to port those two libraries)

Justin-Josef Angel [MSFT]

August 27. 2008 16:33

Awesome job on the port, must have taken a long time. That Assembly.GetName().PublicKey() restriction, it just wants to know if the publickeytoken is null or not, a quick change to

return !assembly.FullName.Contains("PublicKeyToken=null");

shuold remove that restriction, and allow it to run in the browser

Quick Question, the version of Castle seems different than the one used here

www.nablasoft.com/.../

and i'm trying to get this to work in SL. Any thoughts on why the StandardInterceptor has different virtual methods?

Todd Wilder

Comments are closed