sábado, 30 de julio de 2011

Using Prism to compose applications with modules AND other applications

In summary, Prism is a great framework (or guide of development for composite applications, whatever). Prism builds applications with modules. An application is a normal one but with some additional things (bootstrapper or shell) and modules are like applications but without possibility to be executed in standalone. But what about if a requirement is to use prism for building applications with modules AND other applications?

In this post, I will introduce how to reach this scenario.


The proposed solution is to have a ModuleBuilder class to instanciate using Reflection the main files (App.xaml and Shell.xaml) of the Application to be used within a higher application. Also, this can be extended to include some other additional features like either to specify also the region where will be placed at the beginning or to point out some required files necessaries for the application in order to be downloaded into the local server where the higher application is executed.

But where all this configuration is placed? In the ModuleCatalog.xaml from Prism. The ModuleInfo class from Prism has been extended in ApplicationInfo class to include the concrete properties necessaries for a concrete scenario what we need to achieve. Therefore, using an instance of the ApplicationInfo in ModuleCatalog.xaml, we can specify whatever we need. I.e., the needed information to instanciate the main Shell view:

<ModuleCatalog
/** namespaces... **/
xmlns:appInfo="namespace of the implementation">


<ModuleInfo Ref="http://localhost:29220/ClientBin/ModuleA.xap" ..../>
<ModuleGroup InitializationMode="WhenAvailable">
<ModuleInfo Ref="http://localhost:29220/ClientBin/ModuleB.xap" ..../>
<ModuleInfo Ref="http://localhost:29220/ClientBin/ModuleB.xap" ..../>
<ModuleGroup/>


<appInfo:ApplicationInfo Ref="http://localhost:3303/ClientBin/ApplicationSample.xap"
ShellType="Application.Sample.Views.Shell, Applicaation.Sample, Version..."
Region="RegionForApplication"
...
<appInfo:ApplicationInfo/>


</ModuleCatalog>

But how does Prism know whether is a ApplicationInfo or a ModuleInfo instance? Modifying the CreateModule method in ModuleInitializer class from Prism. In the bootstrapper of the higher application, it is required to specify that the implementation of IModuleInitializer will be our concrete implementation where:

public class ConcreteModuleInitializer : XXXModuleInitializer (*)
{
protected override IModule CreateModule(ModuleInfo moduleInfo) 
{
IModule module = null;

if (moduleInfo is ApplicationInfo) 
{
module = new ModuleBuilder(moduleInfo as ApplicationInfo);
}
else 
{
module = base.CreateModule(moduleInfo);
}

return module;
}
}

(*) I typed XXX because depending if your container is MEF or Unity, the ModuleInitializer where you must inherit will be different.

To specify this concrete implementation without modifying ModuleManager class and so on, depending on the chosen dependency injection framework (i.e. Unity or MEF) will be done in a different way but will be something like this (in the Bootstrapper):

protected override void ConfigureContainer() 
{
this.Container.RegisterType<IModuleInitializer, ConcreteModuleInitializer>();
base.ConfigureContainer();
}

Finally, we have in scene to the ModuleBuilder class. Actually, the implementation of this class is quite simple. This will be composed for the instance of the RegionManager class and create a new instance of the Shell view specified. Then, using RegionManager and the region, to place the shell view into the region.

This solution can be adapted to many scenarios. For example, creating an adapter to accept a ModuleBuilder instance and modifying ModuleManager to do it possible. Or even to include other composite applications.

Also, this solution has several considerations or suggestions to pay attention. For example, the application requires some files included in another server, the manner to access to those files is ease if the Uri are absolutes (including the whole address).

No hay comentarios:

Publicar un comentario