3

In some legacy code, there are hundreds of occurrences of the following code snippets:

myObj.ReportGenerator.Preview = reportingObj.PreviewDocument;

... whereas both the "ReportGenerator" and the "ReportingObj" are instances of a third party library and therefore not modifyable.

This code did work well under Windows XP, but running the program in Windows 7 does require the following additional line of code:

reportingObj.Render();
myObj.ReportGenerator.Preview = reportingObj.PreviewDocument;

Unfortunately, there are hundreds of occurences of this piece of code all of the code base, and manually searching for them sounds like quite error-prone a process.

As "ReportGenerator" and "reportingObj" are third party, I cannot change their getter / setter.

What are elegant ways of approaching such an issue?

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
bonifaz
  • 588
  • 3
  • 16

3 Answers3

4

You could wrap ReportingObj in a class of your own in which you just delegate to the original ReportingObj, but for the PreviewDocument property check to see if Render() was called and if not call it - something like this:

public Foo PreviewDocument
{
    get
    {
        if (!_rendered)
        {
            _originalreportingObj.Render();
            _rendered = true;
        }
        return _originalreportingObj.PreviewDocument;
    }
}
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • Interesting idea! Can you please clarify what exactly you mean with "delegate to original"? Do you mean making Foo a subclass of reportingObj's class? – bonifaz Dec 01 '11 at 21:59
  • no use composition instead of inheritance - original reportingObj' is a field inside this class - every method call on the new class just calls the same method on the wrapped instance – BrokenGlass Dec 01 '11 at 22:01
1

You could change the class of myObj, which I assume is under your control, and have the ReportGenerator property return a wrapper class that either calls the original setter of the Preview or calls it after calling Render():

public class ReportGeneratorWrapper
{
     private ReportGenerator m_InnerReportGenerator;

     public PreviewDocument Preview
     {
         get
         {
             return m_InnerReportGenerator;
         }
         set
         {
             if (IsNT6OrAbove)
                 value.Render();

             m_InnerReportGenerator = value;
         }
     }
}
Allon Guralnek
  • 15,813
  • 6
  • 60
  • 93
1

You might find that the least amount of rework will be to create a static class, something like:

public class Previewer
{
     public static PreviewDocumentType PreviewDocument(ReportingObject reportingObj) {
       reportingObj.Render();
       return reportingObj.PreviewDocument;
     }
}

where PreviewDocumentType is the type returned from PreviewDocument and ReportingObject is the type of reporting object.

You can then replace

reportingObj.PreviewDocument;

with

Previewer.PreviewDocument(reportingObj);
competent_tech
  • 44,465
  • 11
  • 90
  • 113