Builders in WCSF

Expect more details about mini-DI in WCSF. Be sure to read previous posts before this one.

WCSF has a two builders (i.e. builders that instantiate the requested objects), they are identical objects (and use identical type and service mappings), but have one crucial difference – singleton policy:

  • ApplicationBuilder – Builder used by the modules and thus in Module Initializers (MI). Its singleton policy is such, that created singletons are stored in the ILocatior. When MI adds a service to the module (e.g. using a container.ServicesNew<SomeService,ISomeService>()), the application builder is used and real singleton service is created. The service is available to all objects in the module and all child modules (unless they overwrite service mapping).
  • PageBuilder – Used by the pages and web controls. WCSF has a lot of slightly tailored WebControls in Microsoft.Practices.CompositeWeb.Web.UI that are subclasses from System.Web.UI, so with WCSF you use the Microsoft.Practices.CompositeWeb.Web.UI.Page instead of System.Web.UI.Page. The singleton policy is such that objects created by this builder are never added to the ILocator thus are never singletons.

Why is there a PageBuilder? The reason is simple, the PageBuilder is used only by the WCSF WebControls to build up the properties of the WebControls. The WCSF WebControls themselves are not instantiated by the ObjectBuilder, but by ASP.NET. The ObjectBuilder comes into a play using the a code in the event methods of the WCSF WebControls (that is the reason why they are there). The WCSF is using PageBuilder to populate the properties of a page using ObjectBuilder, e.g. in OnPreInit method of Page object, OnInit method of MasterPage and so on.

The WebControls themselves are never singletons thus the singleton policy of the PageBuilder and ApplicationBuilder differ.

Crucial difference

Just because PageBuilder doesn’t store singletons doesn’t mean that it always created a new service instance for services. Thanks to default order of the strategies and common ILocator, if it finds a [ServiceDependency], it will locate the service in the ILocator (populated in ModuleInitializer) and uses already existing instance!

The difference in singleton policy is only if created instance is stored in ILocator or not. If there already is an instance, the WCSF will use it.

Basically they tried to work around the problem of how to build up a page we haven’t instantiated. They build it up (=fill public [CreateNew]/[ServiceDependency] properties) in the OnPreInit/OnInit methods of WebControls.

How to use

You use PageBuilder automatically when you use WCSF WebControl. If you really need to use it, call static method WebClientApplication.BuildItemWithCurrentContext(objectToBeBuild).

The ApplicationBuilder property is in Global.asax (the page is derived from the WebClientApplication). To use application builder, follow the code of the BuildItemWithCurrentContext. Basically you need

IModuleContainerLocatorService – WCSF service to locate module from the URL of the page. Use the current URL and get a CompositionContainer of a module.

From CompositionContainer get ILocator and call

webApp.ApplicationBuilder<TypeToBeBuild>(locator, idToBuild, nullOrExistingObject);

For more info, just dive into the source (or not.. I would rather not).