How to: add a base class for Web pages

The Web Client Software Factory has a recipe named Add View (with presenter) which automatically creates a view with presenter implementation for you. The generated code for the view looks like this:

public partial class View1 : System.Web.UI.Page, IView1
{
    private View1Presenter _presenter;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!this.IsPostBack)
        {
            this._presenter.OnViewInitialized();
        }
        this._presenter.OnViewLoaded();
    }

    [CreateNew]
    public View1Presenter Presenter
    {
        set
        {
            this._presenter = value;
            this._presenter.View = this;
        }
    }
}

If you don’t want to have duplicated code in your views, you can create a base class for your views so they look like this:

public partial class View1 : BasePage<View1Presenter>, IView1
{

}

In this article, I’ll guide you through the steps required to update the Web Client Development guidance package to use a base class for your views.

1. Download the CompositeWeb.Extensions.zip file (see below) and extract the solution. The solution contains a project named CompositeWeb.Extensions with the base classes you will use:

BasePage.cs

public class BasePage<TPresenter> : Page
    where TPresenter : IPresenter
{
    private TPresenter _presenter;

    [CreateNew]
    public TPresenter Presenter
    {
        get { return _presenter; }
        set
        {
            _presenter = value;
            _presenter.View = this;
        }
    }

    protected virtual void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            _presenter.OnViewInitialized();
        }
        _presenter.OnViewLoaded();
    }
}

Presenter.cs

public abstract class Presenter<TView> 
    : Microsoft.Practices.CompositeWeb.Presenter<TView>, IPresenter
{
    #region IPresenter Members

    object IPresenter.View
    {
        get { return View; }
        set { View = (TView)value; }
    }

    #endregion
}

IPresenter.cs

public interface IPresenter
{
    object View { get; set; }
    void OnViewInitialized();
    void OnViewLoaded();
}

2. Open your local copy of the Web Client Development guidance package source code.

3. Since we are introducing a base class for presenters, we will need business modules to be created with a reference to the CompositeWeb.Extensions.dll assembly. Also the Web site must have a reference to it. Thus, in the next steps you will modify the guidance package to make the CompositeWeb.Extensions.dll assembly a required file for creating a Web client solution, as illustrated in the following figure.

WCSFrecipe

In the figure above, the Create Web Client Solution recipe wizard was modified to ask the user for the CompositeWeb.Extensions.dll assembly.

To do this, open the file WebClientFactoryPackageRecipesCommonCommonArguments.xml. This file contains arguments that can be accessed by all the recipes.

4. Locate the argument named CompositeWebDlls. This argument specifies the assemblies required for the Composite Web Application Block. It is used by multiple recipes to add references to the block’s assemblies in the projects they generate. It is also used by the Create Web Client Solution recipe wizard to validate that you selected a correct folder for the required assemblies.

<Argument Name="CompositeWebDlls" Required="true" Type="System.String">
  <ValueProvider Type="Evaluator" Expression="
   Microsoft.Practices.ObjectBuilder.dll;
   Microsoft.Practices.CompositeWeb.dll;
   Microsoft.Practices.ObjectBuilder.WCSFExtensions.dll"
    />
</Argument>

5. Add the CompositeWeb.Extensions.dll assembly to the Expression parameter, as shown in the code below:

<Argument Name="CompositeWebDlls" Required="true" Type="System.String">
  <ValueProvider Type="Evaluator" Expression="
   CompositeWeb.Extensions.dll;
   Microsoft.Practices.ObjectBuilder.dll;
   Microsoft.Practices.CompositeWeb.dll;
   Microsoft.Practices.ObjectBuilder.WCSFExtensions.dll"
    />
</Argument>

If you build and register the guidance package now (you can right-click the WebClientFactoryPackage project in Solution Explorer and select Register Guidance Package to do it), you will recognize the following behaviour:

  • The Create Web Client Solution recipe wizards asks you for the CompositeWeb.Extensions.dll assembly.
  • The Create Web Client Solution recipe copies the CompositeWeb.Extensions.dll assembly to the Library folder of your solution.
  • The Create Web Client Solution recipe adds a reference in the Web site and in the Shell module to the CompositeWeb.Extensions.dll assembly.
  • The Add Business Module and Add Foundational Module recipes add a reference in the projects they generate to the CompositeWeb.Extensions.dll assembly.

(yes, you get all that because you simply changed the CompositeWebDlls argument. Nice, isn’t it?)

WCSFSolutionWithExtensionsAssembly

The projects created by the Web Client Solution recipe now have a reference to the CompositeWeb.Extensions assembly.

6. Open the template file WebClientFactoryPackageTemplatesT4ViewView.aspx.cs.t4. This is the template used by the Add View (with presenter) recipe to generate the view implementation. T4 templates allow you to execute C# code to render complex files.

7. Update the class signature to derive from the CompositeWeb.Extensions.BasePage base class and remove the code inside the class definition (because it already exists in the base class). Note that I use the view name + "Presenter" to determine the name of the presenter:

public partial class <#= this.ModuleName #>_<#= this.ViewName #>
: CompositeWeb.Extensions.BasePage<<#= this.ViewName #>Presenter>,
I<#= this.ViewName #>
{

}

8. Open the template file WebClientFactoryPackageTemplatesT4ViewViewPresenter.cs.t4. This is the template for the presenter class.

9. Update the class signature to derive from the CompositeWeb.Extensions.Presenter base class:

public class Presenter : 
CompositeWeb.Extensions.Presenter<I>

Finally, you have to update the default view (named DefaultView) created by the Add Business Module recipe.

10. Open the template file WebClientFactoryPackageTemplatesT4ModuleDefault.aspx.cs.t4. This is the template used to generate the default view implementation of the module. Replace the class code with the following code:

public partial class _Default :
CompositeWeb.Extensions.BasePage, IDefaultView
{

}

Note that in this case we already know the name of the presenter, because the name is fixed to DefaultViewPresenter.

11. Open the template file WebClientFactoryPackageTemplatesProjectsModuleViewsDefaultViewPresenter.cs. This is the template for the presenter of the default view of the module. In this case a Visual Studio template is used for the presenter (this is not a T4 template). Visual Studio templates are used to write templates that do not require complex logic to be unfolded. With these templates you can have parameter substitution but you cannot have C# code embedded, as you can with T4 templates. For example, the parameter $ModuleNamespace$ will be replaced by the namespace of the module (which includes the solution’s root namespace) when Visual Studio unfolds the template.

12. Replace the class signature to derive from the CompositeWeb.Extensions.Presenter base class:

public class DefaultViewPresenter :
CompositeWeb.Extensions.Presenter

Note: altough this is a .cs file, it does not get compiled, because the Build Action property of the file is set to Content. This means that the file will be copied to the output directory as is.

13. Build and register the guidance package. You can use the command Quick Register if you already registered the guidance package before.

Source Code

  • You can get the source code of the CompositeWeb.Extensions project (which includes the code for the base pages) by downloading the CompositeWeb.Extensions.zip file below. If you face problems building the solution, make sure the references to the Composite Web Application Block and ObjectBuilder are correct.
  • You can get the source code of the updated guidance package by downloading the file WebClientFactory Guidance Package with Base Page.zip. Extract it to a local folder where you have the Blocks folder in it. This is required because the guidance package uses components of the Composite Web Application Block. Note that I’ve modified the identifiers of the guidance package so you can register it side by side with the version shipped in the Web Client Software Factory. After registering the guidance package, you will see it in Visual Studio as Web Client Development with Base Page.
  • Important: The code is provided "as is" with no warranties of any kind.



3 Comments

Leave a Reply