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.UIthat are subclasses from
System.Web.UI, so with WCSF you use the
. The singleton policy is such that objects created by this builder are never added to the
ILocatorthus 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
OnInit method of
MasterPage and so on.
The WebControls themselves are never singletons thus the singleton policy of the PageBuilder and ApplicationBuilder differ.
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
[ServiceDependency] properties) in the
OnInit methods of WebControls.
How to use
PageBuilder automatically when you use WCSF WebControl. If you really need to use it, call static method
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).