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 acontainer.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 fromSystem.Web.UI
, so with WCSF you use the
instead ofMicrosoft.Practices.CompositeWeb.Web.UI
.Page
. The singleton policy is such that objects created by this builder are never added to theSystem.Web.UI
.PageILocator
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).