How Does the ModuleInitializer Work?

Topics: Web Client Software Factory
Jul 31, 2007 at 7:10 PM
How Does the ModuleInitializer Work under the hood? Does it use reflection to call the Load method?
Jul 31, 2007 at 8:12 PM
Edited Aug 1, 2007 at 2:42 PM
Hi!


A module initialization class is a class that implements the IModuleInitializer interface. This class contains initialization code that runs when the Composite Web Application Block loads the module. This interface defines two methods, Load and Configure. You implement these methods to perform module initialization tasks, such as registering services or adding site map nodes to the site map.

When loading modules, a Composite Web Application Block service (ModuleLoaderService) reflects on the module assembly and looks for a class that implements the IModuleInitializer interface. When the module assembly contains a class that implements this interface, the application block dynamically instantiates the class and executes its Load and Configure methods.


For more information about module loading and the IModuleInitializer Interface, see Modules in the WCSF help (Inspection the Software Factory Assets -> Application Block -> Composite Web Application Block -> Design -> Modules).

Cheers!

Sebastian Iacomuzzi
http://staff.southworks.net/blogs/siacomuzzi
Jul 31, 2007 at 8:25 PM
As an FYI, I believe I actually show the code that does the module initialization in the following screencast on PnPGuidance:

Web Client Software Factory Composite Web Application Block Part I Screencast

But to answer your questions, yeah, it uses reflection. Here is the code in the ModuleLoaderService where it reflects through all of the types in the Module Assemblies looking for the ModuleInitializer Class:

    foreach (IModuleInfo info in modules)
    {
        Assembly assembly = Assembly.Load(info.AssemblyName);
        CompositionContainer container = string.IsNullOrEmpty(info.VirtualPath) ?
             ((CompositionContainer) compositionContainer) : compositionContainer.Containers.AddNew<CompositionContainer>(info.Name);
        foreach (Type type in assembly.GetTypes())
        {
            if (typeof(IModuleInitializer).IsAssignableFrom(type))
            {
                IModuleInitializer initializer = (IModuleInitializer) container.BuildNewItem(type);
                this._modules.Add(info.Name, initializer);
                initializer.Load(container);
            }
        }
 

Regards,

Dave

__________________________

David Hayden
Microsoft MVP C#
Jul 31, 2007 at 10:36 PM
How often is the moduleinitializer loaded? once for every session? Once for each application access? Once per postback? What happens to the services in between postbacks? Are they serialized and then deserialized?

thank you in advance for your answers?
Feb 19, 2008 at 12:53 PM
Hi all.

This thread seems a bit old, but seemed like the logical place to put this. Firstly, rusdawq400, not sure if you got an answer to this, but the ModuleInitializer gets fired when the Module gets loaded. i.e. Once per Application Startup.

When modules are instantiated, they are stored in the root CompositionContainer, which is a private member of WebClientApplication and therefore gets disposed when the Application ends. Correct me if I'm wrong here, anyone....

My question / note:
I'm a senior developer in an enterprise environment and we've developed a framework on top of the CompositeWeb Application Block to enable rapid and consistent development of web based applications. One thing I noted in CompositeWeb was that, in the ModuleLoaderService, when looking for the ModuleInitializer, no checking was being done to ensure that the Type found was actually a concrete type.

When we developed our framework, we created classes that inherited from most of the classes in CompositeWeb, that would enable us to code some "plumbing". Our version of the ModuleInitializer is an abstract class, and causes the LoaderService to throw an exception. I've modified our version of the CompositeWeb code to check that the Type is in fact a concrete type before instantiating it.

I don't like changing base code, especially if it's provided from a third party and would be maintained by the third party, so I was hoping it would be included in the latest release? Any chance of this?

Regards
Mike Nicol
Coordinator
Feb 29, 2008 at 7:09 AM
MikeNic,
First, you are right: the modules get loaded only on startup, and disposed when the application ends (or when ASP.NET recycles the app pool).

As far as your fix request goes, it looks like we missed this request in this release. Our code was buttoned down about three-four weeks ago, as far as major changes go. We had to update to the latest version of GAX/GAT, and work out a few other issues this month.

The reason p&p ships the source code is for situations like this. You have a scneario we missed. With the code, you can fix it for your organization. Our changes between versions can sometimes be very big, but in this case, I think re-applying the same fix should be very simple for you. Let me know if you have any challenges.

Good luck,
Michael Puleio - patterns & practices
Webhttp://msdn.microsoft.com/practices/
Bloghttp://blogs.msdn.com/mpuleio/
Feb 29, 2008 at 8:55 AM
Great, Thanks for the reply Michael.

We are planning to migrate to the new version of CompositeWeb soon(ish). Once we get there, I'll make the change again.