In my last Silverlight post, Hello Silverlight part 1 – Generating the Project, I started creating a Silverlight-based Hello World application. I described the various pieces that get created by the Project Wizard in Visual Studio 2008. I also started comparing the Silverlight application to a wizard-generated WPF application.
Let me continue looking at the individual pieces that make up a bare-bones Silverlight application. Maybe the convention should be to call it a “Silverlight control”, since that seems a bit more accurate. For now, I’ll stick with Visual Studio’s terminology and call it a “Silverlight application”.
Like our WPF application, the main entry point of the Silverlight application is described by the App.xaml / App.xaml.cs files. In both WPF and Silverlight, these files define a subclass of System.Windows.Application, which serves as the main object loaded at runtime.
In both WPF and Silverlight, we can look at the code in App.xaml.cs and App.g.cs (generated at build time) to get a sense of how the application gets loaded and run. What we see is very different behavior, despite the fact that both App classes appear to derive from System.Windows.Application.
In the WPF application, here’s what happens:
- There is an entry point named Main()
- Creates an instance of the App class
- Calls the InitializeComponent method of the App object
- Calls the Run method of the App object
- Sets App.StartupUri property to point to a Uri object pointing to Window1.xaml, our main window
In the Silverlight application, something very different is going on at startup:
- There is no Main() method
- The App constructor
- Wires up the Application_Startup event handler to the App.Startup property
- Wires up the Application_Exit event handler to the App.Exit property
- Wires up the Application_UnhandledException event handler to the UnhandledException property
- Invokes InitializeComponent
- Instantiates a new Page object (the class for our main page)
- Sets App.RootVisual to point to this page object
- Calls Application.LoadComponent, passing it a new Uri object pointing to App.xaml
Why is the startup behavior so radically different, between WPF and Silverlight, given that the main application appears to be inherited from System.Windows.Application in both cases?
The answer is that, while the class name and namespace are identical, the Application object in Silverlight is a very different animal than the one that is part of WPF. Remember that the WPF application is running against an entirely different .NET Framework than the Silverlight application. WPF is referencing/using the full .NET Framework 3.5 (with pieces from 2.0, 3.0 and 3.5), while the Silverlight application is referencing/using the Silverlight Framework, which is an entirely different set of libraries. While much of the Silverlight framework is a subset of the WPF framework, the Application object is entirely different.
- In WPF, the System.Windows.Application class lives in PresentationFramework.dll
- In Silverlight, System.Windows.Application lives in System.Windows.dll
PresentationFramework.dll is part of the .NET Framework 3.0 and exists on a client system when they install the full .NET Framework (3.0 or 3.5). System.Windows.dll is part of the Silverlight framework and exists on a client system when they install Silverlight.
You can see this by reading the documentation (MSDN). Or you can see how different these Application classes are by doing the following:
- In the WPF application, open the App.xaml.cs file, right-click on Application and choose Go To Definition
- You’ll see that the Application class has a Run method and a StartupUri property, but no RootVisual property
- Now hover over the tab for this window in Visual Studio–you’ll see a temp filename that contains the name “PresentationFramework.dll”
- In the Silverlight application, open the App.xaml.cs file, right-click on Application and choose Go To Definition
- You’ll see a very different Application class, with a RootVisual property, but no Run method
- Hover over the tab again–you’ll see a temp file name containing “System.Windows.dll”
Let’s Stop Here
That’s a good stopping point, for now. We’ve looked just a little bit under the covers in the Silverlight application–enough to see that the main Application object loaded at runtime is very different from the object loaded in the WPF application.