0

I have the following page

public partial class GenericOfflineCommentary : OfflineFactsheetBase
{
}

where OfflineFactsheetBase is defined as

public class OfflineFactsheetBase : System.Web.UI.Page
{
    public OfflineFactsheetBase()
    {
        this.Load += new EventHandler(this.Page_Load);
        this.PreInit += new EventHandler(this.Page_PreInit);
    }

    protected void Page_PreInit(object sender, EventArgs e)
    {
        if (Request.QueryString["data"] != null)
        {
            this.PageData = StringCompressor.DecompressString(Request.QueryString["data"]);
            this.ExtractPageData();
        }
    }
}

OfflineFactsheetBase has the following virtual method:

public virtual void ExtractPageData()
{
    // get stuff relevant to all pages that impmement OfflineFactsheetBase 
}

which is implemented in all pages that impmement OfflineFactsheetBase as follows:

public partial class GenericOfflineCommentary : OfflineFactsheetBase
{
    public override void ExtractPageData()
    {
            // get stuff relevant to an OfflineCommentary page.
    }
}

Currently, only GenericOfflineCommentary's ExtractPageData() is firing. How can I modify this to first run OfflineFactsheetBase's ExtractPageData() and then GenericOfflineCommentary's?

edit: I'm trying to avoid having to call base.ExtractPageData() in every implementor. Is this possible?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
DaveDev
  • 41,155
  • 72
  • 223
  • 385

2 Answers2

3

Make the ExtractPageData method non-virtual, and call a ExtractPageDataInternal virtual method :

public void ExtractPageData()
{
    // get stuff relevant to all pages that impmement OfflineFactsheetBase

    // base implementation
    ...

    // call derived class implementation
    this.ExtractPageDataInternal();
}

protected virtual void ExtractPageDataInternal()
{
    // implementation to be defined by derived class
}

The derived class will only override ExtractPageDataInternal, not ExtractPageData, so the base implementation will always be executed

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
0

Revised after clarification

 public class OfflineFactsheetBase : System.Web.UI.Page
{
    public OfflineFactsheetBase ( )
    {
        this.Load += new EventHandler ( this.Page_Load );
        this.PreInit += new EventHandler ( this.Page_PreInit );
    }

    protected void Page_PreInit ( object sender, EventArgs e )
    {
        if ( Request.QueryString [ "data" ] != null )
        {
            this.PageData = StringCompressor.DecompressString ( Request.QueryString [ "data" ] );
            this.ExtractPageData ( );
        }
    }

    public void ExtractPageData ( )
    {
        // get stuff relevant to all pages that implement OfflineFactsheetBase 
        // ....blah...
        InternalExtractPageData ( );
    }
    // Could be abstract if the class where
    protected virtual void InternalExtractPageData ( )
    {
        // get stuff relevant to all pages that impmement OfflineFactsheetBase 
    }
}

public partial class GenericOfflineCommentary : OfflineFactsheetBase
{
    public override void ExtractPageData ( )
    {
        // get stuff relevant to an OfflineCommentary page.
    }
}

Is OfflineFactsheetBase abstract? If so, make ExtractPageData protected abstract and call it from a public method on the base, see this SO question and answer

Community
  • 1
  • 1
Simon Wilson
  • 9,929
  • 3
  • 27
  • 24
  • but that means that I have to include that line in every implementor's ExtractPageData(), doesn't it? Question Edited to reflect this. – DaveDev May 12 '10 at 11:54
  • 1
    I think I see what you mean, don't know how to add hyperlinks in a comment so edited above to point to an example of the Template pattern – Simon Wilson May 12 '10 at 12:14