Master pages, in the Web Client Software Factory, act as equivalents to the Shell in the Smart Client Software Factory but, unlike their smart client counterpart, they don't benefit from dependency injection.
I've just cooked up a quick way to add dependency injection to master pages in the Web Client Software Factory and, thus, add a Presenter (with the associated Controller).
This can be done just by adding a few lines of code to the Microsoft.Practices.CompositeWeb.WebClientApplication class:
protected void InnerPreRequestHandlerExecute(IHttpContext context)
{
if (HttpRequestHelper.IsHandledByPageHandlerFactory(context.Request.Url.ToString()))
{
ICompositionContainer moduleContainer = GetModuleContainer(context);
// We need to use a non-singleton based builder object here, otherwise
// every object created from the aspx page with the BuildNew attribute
// will be created with hard references on the lifetime container
// and will never be released, causing a memory leak.
CompositionContainer.BuildItem(PageBuilder, moduleContainer.Locator, context.Handler);
Page page = context.Handler as Page;
if (page != null)
{
page.PreInit += new EventHandler(OnPagePreInit);
PrePageExecute(page);
}
}
}
private void OnPagePreInit(object sender, EventArgs e)
{
Page page = sender as Page;
page.PreInit -= new EventHandler(OnPagePreInit);
if (page.Master != null)
{
ICompositionContainer moduleContainer = GetModuleContainer(new CompositeWeb.Web.HttpContext(HttpContext.Current));
CompositionContainer.BuildItem(PageBuilder, moduleContainer.Locator, page.Master);
}
}
With this little change, master pages can be built the same way pages are:
public partial class MasterPage : System.Web.UI.MasterPage, IMasterView
{
private MasterPresenter _presenter;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this._presenter.OnViewInitialized();
}
this._presenter.OnViewLoaded();
}
[Microsoft.Practices.ObjectBuilder.CreateNew]
public MasterPresenter Presenter
{
get { return this._presenter; }
set
{
this._presenter = value;
this._presenter.View = this;
}
}
#region IMasterView Members
// ...
#endregion
}
If you want to see this in the Web Client Software Factory, vote on the corresponding work item.
Update
Apparently I had missed a previous post from Simon Ince on something like this.
There's a discussion on this on the community site.
David Hayden also posted something.
Filed under: .NET, Architecture, ASP.NET, Community, SoftDev, C#, Microsoft, MSDN, MVP, Web, WCSF