Jasper and C#

 

The question “Is Jasper useable from c#?” came up on the Jasper forum.

The short answer is – We designed Jasper specifically for CLR languages with late-bound facilities such as VB and IronPython.  C# doesn’t currently support late-bound calls and hence the answer would be no though some aspects of Jasper may still be applicable.

The long answer is a lot more interesting.

Part of the Jasper framework's functionality provided by the Jasper framework is the generation of  the data classes (representing the underlying database tables and/ or entities) at runtime.  This relieves the developer the burden of writing the data classes themselves or using design time code generation tools.  It also means no deployment cost for the data classes and even allows the database to be changed after the app has been deployed.  A whole lot of goodness for certain types of database apps that don’t want to pay the tax required by most O/R frameworks that exist today and enables a nice iterative, agile development experience.

Since these runtime generated data classes are clr types, one must use a CLR language that supports late binding or use reflection to access members of the data classes.   The latter is very painful and probably more work then actually writing the data classes themselves.

Therefor, Jasper works only with CLR languages that support late binding.  And since we started working on Jasper when the DLR was white board talk, we decided to target Python 1.1 and VB 9 (Orcas versions) - the only CLR languages that supported late binding at the time.

That said, some aspects of the Jasper API can be used from C#.  Let me give a little background of why that is the case by looking at how Jasper allows data class customization.

In Jasper, we wanted a way for users to add the own method/ properties/ fields/ events to the data class generated by Jasper.  To support this, we allowed the user to define a base class.  Then at type generation time, the Jasper runtime would search the app domain to see if a candidate base type exists to derive the new generated type from.  For example, the following type Story would be used as the base type for the runtime generated Jasper data class based on the Stories table:

    Public Class Story

   ' Status is not a column in the Stories table

        Private _status As Boolean

        Public Function GetTitle(ByVal title As String) As String

           'Truncate the title if it is too long

           If title.Length > 200 Then

               Return title.Substring(0, 199)

           End If

           Return title

        End Function

        Public Function IsStoryActive() As Boolean

           Return _status

        End Function

    End Class

Note, the GetTitle method is an example using the of the GetProperty/ SetProperty naming convention that we use to inject custom methods into the generated property Getter/ Setters.  For more information on this see the Project Jasper overview document included with the CTP release. 

The cool thing about using this base class technique is that the methods or properties in the base class can refer to properties that will be added to the generated derived class based on columns in the underlying database table at runtime.

To allow the user to specify as much (or as little) of the base class as they would like,  the Jasper runtime examines the candidate base type to see if any properties or fields are already are part of the base class.  If that is true, then the runtime does not generate those fields/ properties for the generated data class.  It is even possible to specify abstract properties and have the derived class generate the implementation, for example:

    Public MustInherit Class Story

        Public MustOverride Property Title() As String

        Public MustOverride Property Description() As String

    End Class

So the interesting observation here is when the base class specifies the abstract properties, the properties can then be used in C# without requiring reflection:

   

    abstract public class Story

    {

         abstract public string Title { get; set;} 

         abstract public string Description { get; set; }

         abstract public DateTime? PublishedDate { get; set; }

    }

    

    // can now call

    var stories = myDynamicContext.GetQuery("Stories");

    Story myStory = stories[0]; //get first story

    myStory.Title = "New Story Title";

So it would be possible to call properties of the Story instances as long as they were static declared on the Story base type.   However, we are not particularly pleased with this design and experience.  The new C# feature of automatic properties may be a bit better and we are still evaluating its use in Jasper.

That all said, we are actively working on moving Jasper over to the dynamic language runtime - the freshly announced .Net addition to the runtime designed to extent the CLR for dynamic typed CLR languages (VBX, IronPython, IronRuby).  Based on early analysis it is a strong possibility that we move away from the base class mechanism and support a more dynamic model where data class types (or even specific instances!) can be modified at runtime to allow the user to add their own business logic.

The other consideration with respect to using Jasper in C# is that the autobinding components (AutoDataSource, AutoBinder) - see overview document for more information) included in the Jasper framework.  These do not require late binding and/ or a dynamic language to be utilized.  So, this part of the framework will function in C# as it does in the dynamic languages.  This is possible because the binding protocols are already work in a late bound manner and do not required design types unless on is using the design time support offered by the tools.