Michael Wolf

{Binding ME}

20081215 Monday December 15, 2008

Silverlight ConfigurationManager

A problem I hear rumble up from a lot of .Net developers when picking up Silverlight is, “where is ?” My normal answer is, “If it’s not there, do what Microsoft would do… Make your own.” A perfect example of this would be runtime configuration. With the full CLR, so many of us have become accustomed to using ConfigurationManager that reverting to hard-coding values in the binary pains us. By default, Silverlight embeds the ServiceReferences.ClientConfig for service references into the xap, but usually we would prefer to change our service references in our app.config files from our development deployments to production deployments. To overcome this common problem, we have built our own ConfigurationManager.



In the example above, the text is being loaded using the following config file living on the web server

<?xml version="1.0" encoding="utf-8" ?>
<Configuation>
  <AppSettings>
    <Add Key="title" Value="Hello World from configuration manager"></Add>
  </AppSettings>
</Configuation>


This allows us to edit the config on the fly, outside of the compiled xap, just as you would do with a WPF app.config. Using Linq we can load this data into our configuration object by extracting the key and value pairs.

        public static void LoadConfig()
        {
            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            client.DownloadStringAsync(new Uri("app.xml", UriKind.Relative));
        }

        public static void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {

            if (e.Error!=null)
            {
                throw e.Error;
            }

            // load the data
            XDocument config = XDocument.Parse(e.Result);
            var appsettings = from x in config.Descendants("AppSettings").Descendants("Add")
                              select new AppSettings { Key = (string)x.Attribute("Key"), Value = x.Attribute("Value").Value };

            _appSettings = new Dictionary();
            // add to collection
            if (appsettings.Count() > 0)
            {
                foreach (AppSettings y in appsettings)
                {
                    _appSettings[y.Key] = y.Value;
                }
            }

            // notify that its available
            if (ConfigurationAvailable != null)
                ConfigurationAvailable(null, new EventArgs());
        }



Then we can access our configuration values in Silverlight just as we would with the .Net CLR-supplied ConfigurationManager.

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            lblHelloWorld.Text = ConfigurationManager.AppSettings["title"];
        }


One difference with this approach is that every request with in Silverlight must be asynchronous. So there is a little more startup work to get this wired up nicely. In the demo we show a loading screen first while the app.xml file is loaded, and publish back events letting the Silverlight application know when it’s ready to be used.

       private void Application_Startup(object sender, StartupEventArgs e)
        {
            ConfigurationManager.LoadConfig();
            this.RootVisual = new Masterpage();
        }

        void Masterpage_Loaded(object sender, RoutedEventArgs e)
        {
            ConfigurationManager.ConfigurationAvailable += new EventHandler(ConfigurationManager_ConfigurationAvailable);
            LayoutRoot.Children.Add(new Loading());
        }



Another difference is that, since we are using a file with a .xml extension rather than .config, this file is now publicly available (http://dotnet.cynergysystems.com/silverlight/config/clientbin/app.xml), and thus shouldn’t contain sensitive data. This is more similar to a desktop app.config than a web.config scenario. Yet if you are really concerned about exposing somewhat sensitive data, but you must have the flexibility of the config file, you can always encrypt the xml file using the System.Security.Cryptography libs on both server and client (see last weeks post).

Posted by michaelwolf | Dec 15 2008, 04:24:11 PM EST
XML