Dynamically Loading Modules in SCSF
The startup time of any Smart Client Application will increase with number of modules when we are loading all the views in the module controller. In such situations we can load the modules dynamically / on demand.
We need to use two built-in services for dynamic module loading.
ModuleLoaderService: This service is used to load the module whenever it is needed.
FileCatalogModuleEnumerator: This service is used to read an xml file (ProfileCatalog.xml) and retrieve the list of modules mentioned in that xml file.
In this example I will customize the ModuleController.cs of Infrastructure.Module project which will be under source folder of the Smart Client Solution.
Steps For Dynamic Module Loading:
1) Create an xml file(Dynamic.xml) in shell application which will contain the list of modules which should be loaded dynamically. Remove these module names from profile catalog.
Listing 1 – Dynamic.xml
<SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile">
<Modules>
<ModuleInfo AssemblyFile="Module1.dll" />
<ModuleInfo AssemblyFile="Module2.dll" />
</Modules>
</SolutionProfile>
2) Add a FileCatalogModuleEnumerator service to read above file. The following code needs to be written in AddServices method of ModuleController.cs in Infrastructure.Module project.
Listing 2 - Adding Service to the Workitem
Private void AddServices()
{
WorkItem.Services.Add<FileCatalogModuleEnumerator>(new FileCatalogModuleEnumerator("Dynamic.xml"));
}
3) Write a method for dynamic module loading.
The following method will load the module based on the index we pass.
Listing 3 - LoadModule method.
public void LoadModule(int ModuleIndex)
{
FileCatalogModuleEnumerator objFileCatalogModuleEnumerator = WorkItem.Services.Get<FileCatalogModuleEnumerator>();
IModuleLoaderService objModuleLoaderService = WorkItem.Services.Get<IModuleLoaderService>();
IModuleInfo[] modules= objFileCatalogModuleEnumerator.EnumerateModules();
if (!CheckModuleLoaded(modules[ModuleIndex]))
objModuleLoaderService.Load(WorkItem.RootWorkItem, modules[ModuleIndex]);
}
4) The above method will call CheckModuleLoaded method.
The code for CheckModuleLoaded method is as follows
Listing 4 - CheckModuleLoaded method.
The following method will check whether a particular module is already loaded. If the module is already loaded it will return true otherwise false.
private bool CheckModuleLoaded(IModuleInfo module)
{
IModuleLoaderService objModuleLoaderService= WorkItem.Services.Get<IModuleLoaderService>();
IList<LoadedModuleInfo> listLoadedModules;
listLoadedModules = objModuleLoaderService.LoadedModules;
foreach (LoadedModuleInfo loaded in listLoadedModules)
{
if (loaded.Assembly.ManifestModule.Name == module.AssemblyFile.ToString()) return true;
}
return false;
}
Finally we need to call LoadModule method to load a specific module.