There is a annoying bug in the code I posted for building FusionCharts from ASP.NET MVC. If you use one of the fluent methods from the abstract builder class, you lose access to the fluent methods on the concrete. Why is that? Because the fluent methods on the base class all return the base type:
public FusionChartBuilder<T> Caption(string caption) { mCaption = caption; return this; }
This means you can’t write code like the following:
Html.FusionCharts().Pie2D(Model.Whatever, 400, 400, r => r.Count) //Base-class method .Label(r => r.Level.ToString()) //Defined on FusionChartPie2DChartBuilder, won't compile! .PieRadius(250)
The solution is simple, though not exactly clean. By adding a second type parameter and constraining it to objects that derive from FusionChartBuilder (the base class), I can rework my fluent methods to return the type of the derived class instead:
public abstract class FusionChartBuilder<TData, TChartType> where TChartType : FusionChartBuilder<TData, TChartType> { ... public TChartType Caption(string caption) { mCaption = caption; return (TChartType) this; } } ... public class FusionChartPie2DChartBuilder<T> : FusionChartBuilder<T, FusionChartPie2DChartBuilder<T>> { }
Derived classes inherit from the base class by specifying themselves as the TChartType type parameter, which enables the base class to return instances of the derived type. Now you can mix fluent methods from the base class and derived class:
Html.FusionCharts().Pie2D(Model.Whatever, 400, 400, r => r.Count) //Base-class method, but returns instance of FusionChartPie2DChartBuilder .Label(r => r.Level.ToString()) //This is now valid! .PieRadius(250)
look at that hack…
Yeah, but it works, and it doesn’t add (much) complexity for implementers of derived builders. It does however force derived builders to be be sealed since a second level of derivation would re-introduce the same problem…
Nice concepts on this webiste. It’s rare nowadays to find websites with info you’re researching. I am happy I chanced on this page. I will certainly bookmark it or perhaps subscribe to your rss feeds simply to be updated on your new posts. Continue the great work and I’m certain some other individuals researching valued information will actually stop by and benefit from your site for resources.
Such a great article.. Thanks for sharing this article..