When a version of Castle Windsor able to run in Silverlight was released I started to play with it, basically because I have a lot of code that use it inside my line of business infrastructure framework. I’m working on a WPF/Silverlight solution and I’ve developed a framework that work in both the environments.

One of the biggest thing I miss in every ‘Silverlight-enables’ IoC system I tried is the ability to read and parse XML configuration files.

The current release does not allow Silverlight to parse XML configuration file, because all the parser is based on classes that are in the System.Xml namespace and that weren’t included in the Silverlight runtime.

The good news is Silverlight has a very good support for Linq To Xml, so I decided to do a ‘test of feasibility’ and switched the current implementation from using the XmlDom to Linq To Xml.

I have to admit it was more complex than I thought at start (mainly because I had to understand how the parser was written), here are the steps I followed:

  1. Download the ‘Inversion of control’ portion the Castle Windsor trunk an check the project to find the classes to modify: the good news is: all of them are inside a single folder ‘Castle.Windsor\Configuration\Interpreters’
  2. Start with the .Net solution and replace the usages of the ‘old’ XmlDom classes (XmlDocument, XmlNode, etc...) with the new one from System.Xml.Linq (XDocument, XElement, XNode...). Beware it’s not that easy!
    Both these systems act in slightly and sometime subtle different ways so I had to make ‘heavy’ modifications to all the class of the parser.
  3. Keep modifying and fixing the XmlInterpreter and all the other classes until all the tests for the .Net solution pass. At this stage the major modification were the introduction of a LinqToXmlConfigurationDeserializer to replace the standard one and a LinqExtensions class that contains extensions methods to mimic functionalities present in System.Xml.* classes and not directly exposed by Linq classes.
  4. Open up the Silverlight solution, include the new files and verifies it compiles...here some more minor modification were needed to exclude a couple of portions of code that really aren’t available in Silverlight.
    Good! It compiles!
  5. Let’s see an overview of all the files that were modified:
    CastleSilverlightInterpreters All the files we touched are inside the Configuration/Interpreters folders, no other section was modified.
  6. Let’s create a very simple Silverlight Test Application and check it on the ‘Field of Glory’:
    [TestClass]
    public class Tests
    {
        private string config = "<configuration><components>" +
                                "<component id=\"child\" " +
                                           "service=\"SilverlightTest.Domain.IChild, SilverlightTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\" " +
                                           "type=\"SilverlightTest.Domain.Child, SilverlightTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\" />" +
                                "<component id=\"parent\" " +
                                           "service=\"SilverlightTest.Domain.IParent, SilverlightTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\" " +
                                           "type=\"SilverlightTest.Domain.Parent, SilverlightTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\" />" +
                                "</components></configuration>";
     
        [TestMethod]
        public void ComponentRegistrationString()
        {
            WindsorContainer container = new WindsorContainer(new XmlInterpreter(new StaticContentResource(config)));
            // resolve the object
            IParent p = container.Resolve<IParent>();
            Assert.IsNotNull(p);
            Assert.IsInstanceOfType(p, typeof(Parent));
            Assert.IsNotNull(p.ChildConstructorDependency);
            Assert.IsInstanceOfType(p.ChildConstructorDependency, typeof(Child));
            Assert.IsNotNull(p.ChildProperty);
            Assert.IsInstanceOfType(p.ChildProperty, typeof(Child));
        }
    }

and let’s run it:

CastleSilverlightXmlFileResult

Cool! It works: you can now feed up the configuration even from an XML file to the Silverlight version of Castle Windsor too (you can his file from a database a web service or download it directly..that’s up to you).

What’s left to do: as I said before this whole thing started as an experiment and the code is not clean, not optimized nor checked for memory leaks. Plus actually I modified the parser classes and ‘lost’ the previous implementation (I was lazy and I didn’t wanted to write some new tests...I just reused the old ones :D). Some more work is needed to create a full new implementation (parallel to the old one) and write some additional tests for it.

Actually I see only a potential problem and that is how to deal with configuration file inclusion: we should be able to inject an external handler that tells to the processor how to retrieve the resource (we cannot have access to physical files directly (except for those on the Isolated Storage)...so this feature still need some more thinking.

Plus the actual code it’s not very clean and contains a couple of hacks I’m not very proud of and would like to get rid of :D

I think that a good move can be to create a new ‘Castle.Windsor.Configuration’ project and move the configuration code there.

Here is the full source code of this sample if you want to download and try it, it contains the full trunk portion of the Inversion Of Control section in Castle Windsor:

I will submit this code to the Castle Dev Team and see what they think about it.

Related Content