Yesterday, we’ve put the third drop of the Prism V2 project (Composite Application Guidance for WPF and Silverlight) online.
You can download it from here:
In this blog post I’m going to answer the following questions:
- What’s new in this drop?
- What are the Prism V2 module loading scenario’s?
- How is module loading implemented in Prism V2?
- Why the change from module enumerators to module catalogs?
What’s new in this drop?
In this drop, we are starting to address Modularity. We’ve laid down the foundations for two new quickstarts: a static loading quickstart and a remote module loading quickstart. The most interesting of these two is the remote module loading quickstart because it does asynchronous downloading of modules from XAP files, and introduces a new XAML markup based way of defining modules.
Why address modularity in the third drop?
It might be interesting to address why we haven’t started to address modularity until this third drop. In the first two drops, we’ve mostly focused around multi targeting solutions between WPF and Silverlight. This might seem a bit strange, considering Prism is focused on composition. One of the goals of Prism V2 is to enable you to create applications that target WPF on the desktop and Silverlight from the browser using mostly the same codebase. we quickly found that targeting both Silverlight and WPF is not easy, so in true agile fashion, we tried to tackle this high risk unknown factor first. The added benefit is that we are dogfooding the tool we created to help multitargeting and can start capturing guidance on multi targeting applications early.
Prism V2 Module loading scenario’s
When designing the module loading strategy for Prism V2, we first had to come up with the scenario’s we wanted to address.
In a desktop application, you would typically want to create a modular application if you wanted to develop, version and deploy modules independently from each other. Of course these reasons are still valid for Silverlight applications, but we found that in Silverlight there is an other really important for creating a modular application: Minimizing download size. Especially on the web, users are very impatient. So you want users to wait for the minimum amount of time to start using your application. If you deploy your application in one massive 20 Mb Xap file, you are not going to end up with very happy customers.
So you could also use modularity to minimize download time. We defined three categories of modules for this: Core, background and On demand modules.
There is going to be a group of modules that are the bare minimum for your application to run. Most of the time, this will be the shell, shared common infrastructure modules with shared services and one or more functional modules that the user absolutely needs to productively use the application. Of course, speed is essential, so you should try to keep these modules to the minimum size possible.
The core modules, will typically be packaged in the main Xap file. While this main XAP file is downloaded, you can use the built in Silverlight functionality to display a splash screen while the main XAP files are downloaded. Once the main XAP file is downloaded, the core modules will get initialized and the application will start up.
Background downloaded modules
Now there might be a couple of modules that are really important to your application, but the user doesn’t need them right away. However you don’t want them to wait for the module to get downloaded once they actually do need them. So to improve the user experience, you want to download these modules in the background. Modules will be downloaded in order and initialized when they are downloaded.
On demand downloaded modules
Then you might have a group of modules that are only used by a very select group of users (IE: an administration module). This will mostly help in minimizing the installation bandwidth used, because it’s not needlessly downloading assemblies.
Module loading in Prism V2
In Prism V1, there was no concept of module downloading, because all modules where assumed to be available on the file system. Now for silverlight, this approach only works for assemblies that are present in the main XAP file. In Prism V2, we want to support retrieving modules from elsewhere. We’ll support downloading XAP files for Silverlight, but nothing prevents you from downloading modules from the web or from a database in WPF.
This image displays roughly how the module loading pieces relate to each other:
- The bootstrapper creates the Catalog and the Module manager. Then it kickstarts the modulemanager to start initializing the modules.
- The Catalog holds a list of ModuleInfoGroups which is a collection of module info’s. We’ve created a grouping, to make it easier to define which containers (XAP files) hold which modules. It’s also a convenient way to create a group of modules that are ‘Core’.
- The ModuleManager is responsible for coordinating the whole module retrieval and loading process. It will query the Catalog for core modules, background modules. It will also be the point where you hook up events to get notified when modules are downloaded.
- The moduleManager has a list of ModuleRetrievers. We are likely to ship only one retriever: the XapModuleRetriever that downloads silverlight modules. However, this way you can plug in your own retrieval strategies (IE, load modules from a database, webservice or some other means)
- If a module is present (either it was already on the filesystem, or it has been retrieved) the ModuleManager calls the ModuleLoader to instantate the module and call the Initialize method on it. This is the place where you can plug in your own module loading and initialization strategy.
Defining module information in XAML
One other new thing we are supporting is defining module information in XAML. This is different from defining module info’s from a config file, because loading the XAML actually instantiates the ModuleInfo files. This way, it’s easier to create your own ModuleInfo files and extend it with custom properties. Defining modules in XAML looks like this:
This example (from the RemoteModuleLoading quickstart) has two XAP files. Each XAP file has a single ModuleInfo. These modules will be downloaded on a background thread and initialized when they have been downloaded (WhenAvailable)
Moving from ModuleEnumerators to Catalogs of modules
In Prism V1, we have the concept of module enumerators that define which modules are used by the application. For instance, the DirectoryLookupModuleEnumerator would find all modules in a specific directory. After many discussions, we found that this name is a bit confusing. If you think about it, an enumerator in .Net takes a collection and provides a way to walk through that collection. The prism ModuleEnumerators acted more like Module Info providers because they read module information from a certain location (IE: a directory or a config file) and returned the list of module info’s.
In Prism V2, we have defined the concept of a Catalog (of modules). A catalog contains the list of all the modules that are available to the application. Other components, like the ModuleManager can query the catalog for specific groups of modules. Like: “Give me all the Core modules”. Or “Give me all the modules to download in the background”.
There is a bunch of interesting stuff going on in this drop. We are still in the middle of a bunch of changes, but it does give a clear indication of the direction we’re taking.
As always, let us know what you guys think, either by commenting here, commenting on the CodePlex site, or by sending us an E-mail.