Question

I am attempting to have a ReportHandler service to handle report creation. Reports can have multiple, differing number of parameters that could be set. In the system currently there are several different methods of creating reports (MS reporting services, html reports, etc) and the way the data is generated for each report is different. I am trying to consolidate everything into ActiveReports. I can't alter the system and change the parameters, so in some cases I will essentially get a where clause to generate the results, and in another case I will get key/value pairs that I must use to generate the results. I thought about using the factory pattern, but because of the different number of query filters this won't work.

I would love to have a single ReportHandler that would take my varied inputs and spit out report. At this point I'm not seeing any other way than to use a big switch statement to handle each report based on the reportName. Any suggestions how I could solve this better?

Was it helpful?

Solution

From your description, if you're looking for a pattern that matches better than Factory, try Strategy:

Strategy Pattern

  1. Your context could be a custom class which encapsulates and abstracts the different report inputs (you could use the AbstractFactory pattern for this part)
  2. Your strategy could implement any number of different query filters or additional logic needed. And if you ever need to change the system in the future, you can switch between report tools by simply creating a new strategy.

Hope that helps!

OTHER TIPS

In addition to the strategy pattern, you can also create one adaptor for each of your underlying solutions. Then use strategy to vary them. I've built similar with each report solution being supported by what I called engines, In addition to the variable report solution we have variable storage solution as well - output can be stored in SQL server or file system. I would suggest using a container then initializing it with the correct engine, e.g.:

public class ReportContainer{
          public ReportContainer ( IReportEngine reportEngine, IStorageEngine storage, IDeliveryEngine delivery...)
}
}

/// In your service layer you resolve which engines to use
// Either with a bunch of if statements / Factory / config ... 

IReportEngine rptEngine = EngineFactory.GetEngine<IReportEngine>( pass in some values)

IStorageEngine stgEngine = EngineFactory.GetEngine<IStorageEngien>(pass in some values)

IDeliverEngine delEngine = EngineFactory.GetEngine<IDeliverEngine>(pass in some values)



ReportContainer currentContext = new ReportContainer (rptEngine, stgEngine,delEngine);

then ReportContainer delegates work to the dependent engines...

We had a similar problem and went with the concept of "connectors" that are interfaces between the main report generator application and the different report engines. By doing this, we were able to create a "universal report server" application. You should check it out at www.versareports.com.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top