Wednesday, February 25, 2009

Binding dynamic types in WPF using IronPython and DLR


What would be covered in this post?

- Creating classes in IronPython and comparing with C# classes. Adding public properties in IronPython class.

- Using classes/interfaces in IronPython class which is in the hosting assembly. For example, if the application hosting the DLR and executing the IronPython class at runtime has an interface IDyn, this article covers on how to use that interface within the Python script.

- Accessing the dynamic type created in the IronPython and making an instance of it.

- Finally, binding the dynamic type to WPF controls.

Pre-Requisites

Before, we get started, I recommend you go through the article I posted previously which shows how to use the IronPython engine within .NET applications. I will be using the same PythonEngine class with a new method added as shown below.

   1: public T GetDynamicType<T>(string scriptFile)


   2:         {


   3:             try


   4:             {


   5:                 var source = engine.CreateScriptSourceFromFile(scriptFile);


   6:                 source.Execute(scope);


   7:                 var SomeClass = engine.GetVariable(scope, "DynObject");


   8:                 var t = engine.Operations.Create(SomeClass);


   9:                 return (T)t;


  10:             }


  11:             catch (Exception ex)


  12:             {


  13:                 Debug.WriteLine(ex);


  14:             }


  15:             return default(T);


  16:         }





In the above method, we see that the engine (refer to the previous article, it would be useful if you want to understand it) creates an instance of ScriptSource object from the script file. Then we pass the current ScriptScope we created earlier and pass it to the Execute() method which would make the class be available to be used. Line 7 shows using GetVariable() on the engine and we pass the scope (which knows where the class we are looking for is) and also the name of the class, which is DynObject. Once we have the class (I assume its the IL, or at least i understood it that way), we use the Create() method on the engine passing the class which would return instance of that class. Then we simply return the instance by casting it to type T (a generic, so we use default(T) which is like null but for generics). So this method basically executes a python script and returns an instance of the class we specify. May be I would just refactor the method to make it look like shown below and which allows the method itself to be more generic than it is.





   1: public T GetDynamicType<T>(string scriptFile, string className)


   2:         {


   3:             try


   4:             {


   5:                 var source = engine.CreateScriptSourceFromFile(scriptFile);


   6:                 source.Execute(scope);


   7:                 var SomeClass = engine.GetVariable(scope, className);


   8:                 return (T)engine.Operations.Create(SomeClass);


   9:             }


  10:             catch (Exception ex)


  11:             {


  12:                 Debug.WriteLine(ex);


  13:             }


  14:             return default(T);


  15:         }




The method is used as shown below.





   1: object o = pe.GetDynamicType<Object>("DynObject.py", "DynObject");




Creating IronPython class with public properties



Consider the C# class shown below.





   1: public class DynObject : IDyn 


   2: {


   3:    public string Name { get; set; }


   4:    public string Age  { get; set; }


   5: }




The class is named DynObject which implements the interface IDyn and which has two public properties Name and Age. The python code for the same is shown below.





   1: class DynObject(IDyn):


   2:   


   3:   def __init__(self): # this is the constructor


   4:     self._name = None # initialized to NULL


   5:     self._age = None # initialized to NULL


   6:     


   7:   def __getName(self):


   8:     return self._name


   9:     


  10:   def __getAge(self):


  11:     return self._age  


  12:     


  13:   def __setName(self,value):


  14:     self._name = value


  15:     


  16:   def __setAge(self,value):


  17:     self._age = value


  18:     


  19:   Name = property( # this is the Name property. use "property"


  20:      fget= __getName, # getter


  21:      fset= __setName  # setter


  22:   )


  23:   


  24:   Age = property(


  25:      fget=__getAge,


  26:      fset=__setAge


  27:   )






The statement followed by # are the comments. Hope they help you relate the classes properly and with that one should be able to write basic classes on their own.



Importing Namespaces in IronPython and setting up default namespaces



Now the problem with the above script when you Execute() it in the method I first discussed is that it would complain about not knowing what IDyn is. So basically we do an import the namespace. But the interface IDyn was created inside a namspace “Dynamics” which is the same application that is executing the python script. Had it been a ‘Debug’ then one could have done the following to import System.Diagnostics.*





   1: import clr


   2: clr.AddReference("System.Diagnostics")


   3: from System.Diagnostics import *


   4: # from System.Diagnostics import Debug 


   5: # if you just want to import Debug class




But the issue I has was to know what assembly should I mention in the AddReference and I was wondering if there was a good way to import some default namespaces into the engine without having the user mention them manually. For that reason we have ScriptRuntime.LoadAssembly(Assembly asmToLoad) which can be used to add reference to assemblies of your choice. In order to support this, I felt that it would be a good idea to load the assemblies before you even generate the ScriptSource object from the script file. For this reason, I modified the PythonEngine (the wrapper I talked about in my previous post on IronPython) constructor and now it looks like as shown.





   1: private PythonEngine(){


   2:             engine = Python.CreateEngine(new Dictionary<string, object>() { 


   3:                 { 


   4:                 "DivisionOptions", PythonDivisionOptions.New 


   5:                 } //using Dictionary Initializer ;)    


   6:             });


   7:             var runtime = engine.Runtime;


   8:             //Load the assemblies into the engine's runtime.


   9:             runtime.LoadAssembly(typeof(Debug).Assembly);


  10:             runtime.LoadAssembly(typeof(string).Assembly);


  11:             runtime.LoadAssembly(typeof(IDyn).Assembly);


  12:             scope = engine.CreateScope();


  13: }




What should be of interest to import default assemblies into the system are in lines 7-11. Then on we can move on to add the imports to the python file as shown. No more AddReference() required.





   1: from System.Diagnostics import Debug


   2: from Dynamics import IDyn


   3:  


   4: class DynObject(IDyn):


   5:   


   6:   def __init__(self):


   7:     Debug.WriteLine("here")


   8:     self._name = "buddi"


   9:     self._age = "22"


  10:     


  11:   def __getName(self):


  12:     return self._name


  13:     


  14:   def __getAge(self):


  15:     return self._age  


  16:     


  17:   def __setName(self,value):


  18:     self._name = value


  19:     


  20:   def __setAge(self,value):


  21:     self._age = value


  22:     


  23:   Name = property(


  24:      fget= __getName,


  25:      fset= __setName


  26:   )


  27:   


  28:   Age = property(


  29:      fget=__getAge,


  30:      fset=__setAge


  31:   )




Note that you still need to do the “from  NAMESPACE import CLASSNAME/*”.



How about integrating the python code in WPF?



The IDyn was just an empty interface which was added to explain how one could use .NET interfaces within IronPython classes. So back to the WPF application, which is simple and straight forward. The XAML code for the Window is shown below.





   1: <Window x:Class="DynamicBinding.Window1"


   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"


   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"


   4:     Title="Window1" Height="300" Width="300">


   5:     <StackPanel>


   6:         <TextBlock Text="{Binding Name}" Background="Red" Margin="5" Height="30"/>


   7:         <TextBlock Text="{Binding Age}" Background="Blue" Margin="5" Height="30"/>


   8:     </StackPanel>


   9: </Window>




From the bindings shown above, the Name property is looked for in the DataContext of TextBlock, StackPanel or Window. So in the code-behind we use our PythonEngine to obtain an instance of the dynamic type we created and set the DataContext of the window to the instance we obtained. The code behind is shown below.





   1: using System;


   2: using System.Windows;


   3: using Dynamics;


   4:  


   5: namespace DynamicBinding


   6: {


   7:     /// <summary>


   8:     /// Interaction logic for Window1.xaml


   9:     /// </summary>


  10:     public partial class Window1 : Window


  11:     {


  12:         private PythonEngine pe = PythonEngine.Engine;


  13:  


  14:         public Window1()


  15:         {


  16:             InitializeComponent();


  17:             object o = pe.GetDynamicType<Object>("DynObject.py", "DynObject");


  18:             this.DataContext = o;


  19:         }


  20:     }


  21: }




This ability to bind WPF controls to dynamic types would be a great feature if you would like to generate UI based on the user controlled params. This would be even easier with the dynamic support in C# 4.0 which I hope to see another release during the MIX 2009.



Next I would like to work on generate the python classes from XML which would be provided by the user and even the XAML would be generated from the XML. This would be the basis for my reporting suite which would be powered by Silverlight, DLR and WCF.

Wednesday, February 18, 2009

Make your .NET application extendible using DLR : IronPython

There are different ways to define this – extensibility in applications, adding macro capability to your applications, providing add-in like facility in .NET applications. For me, all of this mean the same – ability to modify your application (data or the UI) at runtime by means of scripts. Like I mentioned in the previous post, I wanted to dig into DLR or Dynamic Language Runtime which is basically a framework that could be used to provide dynamic languages support on the .NET platform. Even though I am not much interested in giving up C# for dynamic languages like Python or Ruby, I was very much keen to add facility to make my applications extensible using these languages (to tell you the truth, I am more comfortable with JavaScript or Groovy than any of these).

Anyway, I worked on an application which displays a datagrid and one could modify that the data being displayed using Python script at runtime. The way I did it was to host IronPython inside C# using the DLR framework.

The article would be a detailed step by step procedure on each and every piece of code that has been written so that it helps the readers get familiar with the following

  1. Using WPF Datagrid and databinding. Also shows Dependency Properties.
  2. How to refresh WPF Datagrid items.
  3. Hosting IronPython inside C# applications.
  4. Passing data to and fro between C# and IronPython script.

Shown below are the screenshots for the application that we will be looking through.

image image image
Application when started First time execution  Subsequent executions

Figure 1 shows the application when it first started. The data that appears in the grid has been generated on the fly for simplicity. The application provides two buttons whose titles are descriptive enough – one for running the script that modifies the data and the other for launching the script in notepad.

Figure 2 is when first the script is applied. Notice the amount of time it takes (2.1 seconds). It looks slow and the majority of the time, I guess, is consumed for initialization of the IronPython engine in the DLR. The python script that was executed looks at the age of the person and classifies them accordingly. Notice that the persons over 60 have their address as “senior citizen at work”. (Address is a pretty lame field for description, anyway I am lazy now to change it).

Figure 3 shows two subsequent executions which has the same effect as earlier but the script has been modified to change the description from “senior citizen at work” to “seniors”. This was to show that the script could be modified outside the application and yet it would be faster since the engine is already initialized (the way I wrote the evaluation). It takes .18 seconds to operate on 50 K tuples which I personally think is very good.

I hope you now have a clear picture on what we are trying to achieve. To further enhance your understanding, let us look at the python script. Note that the application was designed in such a way that it passes the list of persons using the variable “Context” and expects the modified list of person in “Output”.

   1: import clr


   2: clr.AddReference('System')


   3: from System import *


   4: from System.Diagnostics import Debug


   5:  


   6: for person in Context:


   7:   age = person.Age


   8:   if age >= 60:


   9:      person.Address = "Seniors"  


  10:   elif age > 25 and age < 60:


  11:      person.Address = "Adult"


  12:   elif age <=25 and age > 18:


  13:      person.Address = "Growing"


  14:   else:


  15:      person.Address = "Minor"


  16: Output = Context




The first 4 lines brings in the .NET assemblies and I import System.Diagnostics.Debug class just to show how to import .NET classes into IronPython code. The python script is pretty much readable (and you would not believe how long it took me to figure out how to write that).



Anyway lets get started by creating a new WPF project. Add the references to IronPython and DLR assemblies. Also add reference to WPF Toolkit assembly. The references should look like shown below.



image



XAML for the application.





   1: <Window x:Class="DynamicGrid.Window1"


   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"


   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"


   4:     Title="Click On Apply Filter to apply the Python Filter" Height="600" Width="300" 


   5:         WindowStyle="ThreeDBorderWindow"


   6:         xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit">


   7:     <Grid>


   8:         <Grid.RowDefinitions>


   9:             <RowDefinition Height="*"/>


  10:             <RowDefinition Height="35"/>


  11:             <RowDefinition Height="70"/>


  12:         </Grid.RowDefinitions>


  13:         <my:DataGrid Name="myGrid" ItemsSource="{Binding DataSource}" CanUserAddRows="False" CanUserResizeColumns="False">


  14:         </my:DataGrid>


  15:         <StackPanel Orientation="Horizontal"  Grid.Row="1">


  16:             <Button Name="ApplyRubyFilter" Content="Apply Python Filter" Click="ApplyRubyFilter_Click" Margin="5"


  17:                />


  18:             <Button Name="OpenScript" Content="Edit Python Script/Filter" Click="Edit_Script_Filter" Margin="5"/>


  19:         </StackPanel>


  20:         <ScrollViewer Grid.Row="2">


  21:             <TextBlock Name="Status" Text=""/>


  22:         </ScrollViewer>


  23:     </Grid>


  24: </Window>




Line 6 imports WPF toolkit which can then be used within the xaml file. Line 13/14 shows WPF datagrid being added to the first row of the container grid. Notice that it is bound to DataSource property. So it looks for this property in the datacontext of itself or the parent containers. For this, I added a dependency property with name “DataSource” in the code behind of the current window( which is Window1.xaml.cs. Shown below is the code for the property as well as the constructor.





   1: public IEnumerable DataSource


   2:        {


   3:            get { return (IEnumerable)GetValue(DataSourceProperty); }


   4:            set { SetValue(DataSourceProperty, value); }


   5:        }


   6:  


   7:        // Using a DependencyProperty as the backing store for DataSource.  This enables animation, styling, binding, etc...


   8:        public static readonly DependencyProperty DataSourceProperty =


   9:            DependencyProperty.Register("DataSource", typeof(IEnumerable), typeof(Window1), new UIPropertyMetadata(null));


  10:  


  11:        private IEnumerable<Person> _tempData;


  12:  


  13:        public Window1()


  14:        {


  15:            InitializeComponent();


  16:            this.DataContext = this;


  17:            _tempData = GenerateData();


  18:            myGrid.AutoGenerateColumns = true;


  19:            UpdateDataSource(_tempData);


  20:        }




For the dependency property, I usually use Visual Studio code snippet (Ctrl+K,X, Then NetFX30).



Now talking about the constructor, line 16 sets the DataContext of the window to itself. So the grid would finally find DataSource property in here. Note that you could set DataContext within XAML as shown below.





   1: <Window x:Class="DynamicGrid.Window1"


   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"


   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"


   4:     Title="Click On Apply Filter to apply the Python Filter" Height="600" Width="300" 


   5:         WindowStyle="ThreeDBorderWindow"


   6:         xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit"


   7:         Name="myWindow" DataContext="{Binding ElementName=myWindow}">




Line 7 in the above code snippet would be of interest to set DataContext to the current Window class in XAML.



Anyway back to what the constructor was doing. It invokes GenerateData() which generates a list of Person objects and assigns it to _tempData. This variable is what we would be using to pass to the Python script. Code for the GenerateDatat() is shown below.





   1: public IEnumerable<Person> GenerateData()


   2:         {


   3:             var list = new List<Person>();


   4:             Random rand = new Random();


   5:             for (int i = 0; i < 50000; i++)


   6:             {


   7:                 var person = new Person()


   8:                 {


   9:                     Name = "Name " + i,


  10:                     Age = rand.Next(100),


  11:                     Address = string.Format("Address {0}", i * 10)


  12:                 };


  13:                 list.Add(person);


  14:             }


  15:             return list.AsEnumerable();


  16:         }




Finally the constructor invokes UpdateDataSource() passing the data that the grid has to bind to. As you can expect the UpdateDataSource method just sets the value on the DataSource and performs a refresh on the datagrid items. Since DataSource is a dependency property, the grid automatically loads the datasource.





   1: private void UpdateDataSource(IEnumerable<Person> source)


   2:         {


   3:             DataSource = source;


   4:             myGrid.Items.Refresh(); //refresh the grid manually.


   5:         }




Now when the user clicks the “apply filter button”, the python script has to be executed. Code that does just that.





   1: private void ApplyRubyFilter_Click(object sender, RoutedEventArgs e)


   2:         {


   3:             var temp = ApplyIronPyFilter();


   4:             Debug.WriteLine(temp.GetType().Name);


   5:             if (temp != null)


   6:                 UpdateDataSource(temp.ToList());


   7:         }




For now, lets just say ApplyIronPyFilter does everything that it needs to execute the script on the _tempData and returns a new list of items. Ignore the line 4 which I added to verify what was being returned from the Python script. And if there is something in what is being returned, I update the datasource with that list.



Before we look into what ApplyIronPyFilter does, let us see the wrapper for the IronPython engine that I made to make things easy.





   1: using System;


   2: using System.Collections.Generic;


   3: using System.Diagnostics;


   4: using IronPython;


   5: using IronPython.Hosting;


   6: using Microsoft.Scripting.Hosting;


   7:  


   8: namespace DynamicGrid


   9: {


  10:     public class PythonEngine


  11:     {


  12:         private ScriptEngine engine;


  13:         private ScriptScope scope;


  14:  


  15:         private PythonEngine()


  16:         {


  17:             engine = Python.CreateEngine(new Dictionary<string, object>() { { "DivisionOptions", PythonDivisionOptions.New } });


  18:             scope = engine.CreateScope();


  19:         }


  20:  


  21:         private static PythonEngine _pe;


  22:  


  23:         public static PythonEngine Engine


  24:         {


  25:             get


  26:             {


  27:                 if (_pe == null)


  28:                     _pe = new PythonEngine();


  29:                 return _pe;


  30:             }


  31:         }


  32:  


  33:         public void SetVariable<T>(string name, T value)


  34:         {


  35:             scope.SetVariable(name, value);


  36:         }


  37:  


  38:         public T Evaluate<T>(T Context, string scriptFile)


  39:         {


  40:             this.SetVariable<T>("Context", Context);


  41:             try


  42:             {


  43:                 var source = engine.CreateScriptSourceFromFile(scriptFile);


  44:                 source.Execute(scope);


  45:             }


  46:             catch (Exception ex)


  47:             {


  48:                 Debug.WriteLine(ex);


  49:             }


  50:             //execute the script


  51:             //return value from "Output"


  52:             T value = default(T);


  53:             if (scope.TryGetVariable<T>("Output", out value))


  54:                 return (T)value;


  55:             return default(T);


  56:         }


  57:     }


  58: }




I am not going into details for each and every line of code that I am writing (may be sometime later).  But I would like to talk a little about Evaluate method which I think is important. The first parameter it takes would be the input for the text and as you can see in Line 40, it is being set as a Python variable with name “Context”. Similarly line 53 attempts to read a variable “Output” using TryGetVariable method on the “scope” object which was created in the constructor of the PythonEngine class. Lines 41-49 shows on how to load the script from a file and execute it. I would recommend you to look at the whole 58 lines of code for the PythonEngine since it is simple and yet important. At least you are required to look at the constructor and the SetVariable,Evaluate methods.



Finally, we come to the ApplyIronPyFilter method which as you can expect would use the PythonEngine#Evaluate() method passing the context as _tempData and path to the python script file that would be executed. The method then captures the return value from the Evaluate method and returns it back. Look at the source code.





   1: private IEnumerable<Person> ApplyIronPyFilter()


   2:         {


   3:             var sw = Stopwatch.StartNew();


   4:             try


   5:             {


   6:                 var engine = PythonEngine.Engine;


   7:                 return engine.Evaluate<IEnumerable<Person>>(_tempData, @"test.py") ;


   8:             }


   9:             finally


  10:             {


  11:                 sw.Stop();


  12:                 Status.Text += ("Time taken for Python Script : " + sw.ElapsedMilliseconds + " milliseconds \n");


  13:             }


  14:         }




Also shown is code on how to time the execution which is set to the Text property of the “Status” which is a textblock (look at the XAML). Looks like we are done with the most important pieces of source code that makes this application extendible.



I personally think it would be really cool if we have a IronGroovy kind of runtime. Having worked on Groovy for fairly complex applications (during my Masters), I am a huge fan of Groovy.



I totally had fun doing research on making this application work. I hope you find all the information you need to get started embedding DLR into your applications. Please let me know if you have any specific questions.



I got the book “Data Driven Services with Silverlight 2 by John Papa” which looks like book. Anyway I expected it to be dedicated to WCF driven data applications in Silverlight but that should be fine. I think the book would be very useful to understand more about data-driven silverlight applications, just that the source of data differs. I am actually looking for a good WCF book (should be comparable in good-ness with Programming WPF by Chris Sells). If you know of any good one, drop a comment.

Tuesday, February 17, 2009

Research : Silverlight Data, WCF as a Service and few others

Like I mentioned in one of my previous posts, I was thinking on how to develop a report development suite using Silverlight and WCF as the backbone. In that process I had several questions for which I had been digging around the internet to see if I could get some answers. The intention of this post is to log my findings. Please note that I do not own the content posted here and I appreciate all the effort that the authors have put into writing these articles.

1. How would I bind unknown objects to the Silverlight Datagrid (or any grid for that matter)?

Problem: My plan is to take in queries that generates reports and run them against a database (SQL or Oracle). The returned results should bind to the datagrid. So I am not sure on what columns would be returned from the result set and more over I do not know what type of class should I be creating in advance so as to support all the possible results returned. Some times it might just return EmployeeName, EmployeeId while some other time it might just return EmployeeName, EmployeeSalary, EmployeeHikePercent. So the question is on how to generate dynamic typed objects in C#.

Solution: One idea is to generate IEnumerable<IDictionary> as described in Vladimir’s blog.

How-to-bind-Silverlight-DataGrid-from-IEnumerable-of-IDictionary

2. I would like to get a general idea on how to go ahead developing business/enterprise class applications in Silverlight. Is there a reference implementation or a tutorial?

Problem: Doing simple stuff in Silverlight is fairly easy but developing enterprise line-of-business applications using Silverlight would require decent experience with the new programming model that silverlight brings in. So learning from other’s experience would be great.

Solution: Look at Chris Andersons’ wonderful series on developing LOB applications in Silverlight.

Building-a-Framework-for-Silverlight-Line-Of-Business-Applications.aspx

3. Now let us think deep. Let us assume that somehow I am able to send my data using WCF service. The problem would be – what the most performance efficient way to implement paging or infinite scrolling?

Problem: you have the datasource and the most common requirement is to implement Paging functionality in the grid. So how would I go about doing this. Are there any clever methods?

Solution: Look at the following links. They are all very useful.

scrolling-through-large-resultset-with-silverlight-2-beta1-and-linq-to-sql.aspx

stealth-paging-datagrid.aspx

4. How about support for large datasets returned from the service?

I know with my 0.01 cent worth knowledge on WCF, it is too early for me to think on these lines but anyway the problem that I foresee is that if WCF service sends large dataset to the Silverlight client, the client application eventually runs out of memory. So how would I handle it.

So far, I just found this - http://weblogs.asp.net/cibrax/archive/2008/06/10/streaming-large-content-with-wcf-and-deferred-execution.aspx

5. More on large datasets, sorting, grouping on paged datagrids.

Problem: Let us assume that we have loaded only the first page of data in the datagrid and when we sort, the grid only sorts that particular page. But the client expects to see the whole data sorted and return only the first page. How would I achieve this with Silverlight datagrid and WCF as a data providing service?

Solution: On this one, I am yet to find proper solutions. May be I am not looking right. so if anyone reading this blog has prior idea on how to  do this, I would be glad if you can share your experience or idea (need not share code as such, I am just looking for a proper pattern to do this).

6. The users viewing the report might want to apply certain filters. How would I go ahead and provide such a functionality?

Problem: Let us assume we displayed certain report. Now it would be nice if the user can view only those records which meets his criteria. So we provide the user with some filtering capabilities. The user would add a new filter expression which would be something like “ColumnX = 100”. So the filter should be evaluated and be applied on the dataset and display only those records which satisfy the filters specified.

Solution: One way is to use dynamic linq (http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx) which allows string LINQ expressions. So the user would be writing LINQ expressions which would be evaluated runtime and the result would be returned.

7. What if the user wishes to have more control, then he could write a filter in languages like IronRuby, IronPython and Managed JScript.

Problem: Consider the same scenario as above but with a more complex scenario. The user wishes to execute some script on the result returned, save the script as a filter and apply it on the report as he wishes to. So how would we provide such a capability ?

Solution: The idea would be to use DLR platform which provides scripting ability using DLR languages like IronRuby, IronPython and Managed JScript. For a basic understanding on how to enable your applications to have scripting ability, you might want to look at the following articles which discuss the subject in more detail.

http://blogs.microsoft.co.il/blogs/shayf/archive/2009/02/01/make-your-application-extendable-using-the-dlr.aspx

http://ironruby.rubyforge.org/wiki/wiki.pl?ExecutingIronRubyFromCSharp

http://www.ironruby.net/Documentation/CLR_Interop

http://msdn.microsoft.com/en-us/magazine/cc163284.aspx

My next immediate task is to be able to come up with a detailed article on how to make a simple extendable grid using WPF datagrid and IronRuby as scripting platform. Hopefully I should be done with it today and get a more detailed understanding on how things work.

8. Microsoft’s Silverlight Datagrid is very basic. Can I have a better grid that is free to use?

Problem: Silverlight datagrid does not provide functionality like grouping data, display summary items straight out of the box and requires more work.

Solution: Use DevExpress AgDataGrid the free silverlight datagrid control which has nice features like summary rows, sorting, grouping and many others that the Silverlight datagrid lacks.

9. So where else can you think of using scripting functionality on the reporting suite.

One idea is to auto-generate Ruby classes for a query based on the result returned, load them using DLR and generate data source out of it. But it might not actually be a great idea since I have no clue on how well it performs or how well it would act as a Data Transfer Object.

Custom Summary Rows : AgDatagrid allows us to display custom summary items which is very flexible. So we can extend the same flexibility to the report developer. He would write a script using one of the DLR languages which would be executed to get the custom summary value. This would make the application more flexible and depending on how well the developers are with scripting the possibilities are endless. Combined with filters functionality, this would turn out to be a great application to use – powerful and yet simple for basic reports.

Custom Event Handlers: Let us say the report has an event ReportDataFetched. Reports developer can specify a custom script which handles how the data would be filtered before actually rendering the data. He might want to filter out some data without even showing the user. Similarly such other events could be applied using scripting. For example, when we provide scheduling functionality we might have an event that says “ExecutionCompleteDataReady” which can execute a SendEmail script that the user would provide us.

With proper optimization of the script such that the end user does not feel bugged, DLR would be a great platform to make your applications extensible. You just need to figure out ways to work with it.

10. Let us say everything is going well with the reporting suite and finally I would like to implement the following – Charts, Dynamic Charts, Exporting data to Excel-PDF-CSV, Exporting charts as images. How would I be doing all this?

Silverlight, at this moment, does not allow data to be printed at the client. So the conversion should be done on the service. For this, I found a codeplex project called Exporter (Exporter). In order to generate charts in Excel documents, one could use the help of this MSDN article. Some discussion on this subject is available here.

As of the charts, Silverlight charts looks like a great suite that could be used. Another option is to use Visifire controls but they are not free for commercial use.I received a comment from Chirag, Product Manager at Visifire stating that Visifire is indeed free for commercial applications if it conforms to the GPL. As a more important note, Silverlight Toolkit is a very good suite that one could use in many ways.

If we move ahead on how to export Silverlight control rendered as an image, as a starting place, I would look at Silverlight Contrib project. This project provides a Silverlight implementation of XamlWriter which can be used to get the XAML for the current silverlight element and then render it to a PNG. (Use this article)

I am glad on how this blog has turned out to be. It really helped me to think in the proper direction. Now in the next article I would focus on making extendible grid and demo the filter functionality with the help of DLR, I guess I would pick Ruby (I need to learn on how to use it, though).

Sunday, February 15, 2009

C# 3.0 & LINQ : Auto-implemented Properties

As my quest to understand the finer details of LINQ which I would present to my team at Imageright, I thought it would be a great idea to start from scratch and look at each functionality of C# language which enables LINQ. In that process, I start with Auto-implemented Properties.

Defining auto-implemented property

   1: public sealed class Person{


   2:  


   3:        public string FirstName { get; set; }


   4:  


   5: }




The above class Person, defines an auto-implemented properties. you see can see both setter and getter defined. We will dig more into these in a while before which we should look at the compiler generated code. I used Reflector to decompile the source and this is what it looks like.





   1: public sealed class Person


   2: {


   3:     // Fields


   4:     [CompilerGenerated]


   5:     private string <FirstName>k__BackingField;


   6:  


   7:     // Properties


   8:     public string FirstName


   9:     {


  10:         [CompilerGenerated]


  11:         get


  12:         {


  13:             return this.<FirstName>k__BackingField;


  14:         }


  15:         [CompilerGenerated]


  16:         set


  17:         {


  18:             this.<FirstName>k__BackingField = value;


  19:         }


  20:     }


  21: }


  22:  





Clearly, nothing exceptionally new has been added to the IL and the compiler just generates C# 2.0 like properties from the above property – thus aptly named auto-implemented properties. Notice that a hidden backing field is used to support the property.

CompilerGeneratedAttribute[System.Runtime.CompilerServices] is applied to any element that is not user written and is automatically generated by the compiler. This attribute can be used to determine if an element is generated by the compiler.



Read-Only Properties





   1: //read-only property


   2: public readonly string LastName { get; set; }




The above shown way is INCORRECT. The compiler does not allow readonly keyword on the auto-prop. The way you achieve read-only is as shown below.





   1: //read-only property


   2: public string PersonCode { get; private set; }




The compiler generated code seems to add “private’ before the setter, just like the way we did.





   1: public string PersonCode


   2:   {


   3:       [CompilerGenerated]


   4:       get


   5:       {


   6:           return this.<PersonCode>k__BackingField;


   7:       }


   8:       private [CompilerGenerated]


   9:       set


  10:       {


  11:           this.<PersonCode>k__BackingField = value;


  12:       }


  13:   }




As a side-note, auto-implemented properties can also be static.





   1: //statics are allowed


   2: public static string ClassName{


   3:             get;


   4:             set;


   5: }




Write-Only Properties



Well, this might not make sense to use (in practical scenarios), but write-only properties are also allowed. When one tries to read a write-only property, the compiler generates the following error.



Error    1    The property or indexer 'LinqBasics.Person.SecretCode' cannot be used in this context because the get accessor is inaccessible



Shown below is a write-only property.





   1: public string SecretCode { private get; set; }






Also note that, you can re-order the get and set [does not matter, though].





   1: public string Ext { private set; get; }


   2: //order of set and get does not matter




What are not allowed?



The accessibility modifier for the accessor should be more restrictive than the property or the indexer.



The following property is invalid.





   1: private string ExtensionWide { private get; set; }


   2: //private get is not more restrictive than private applied on the property


   3: //thus it is not a valid declaration




Similarly, a private property cannot have a public accessor.



You cannot specify accessibility modifiers for both accessors of a property or indexer.



The following is invalid.





   1: public string InvalidProperty { private get; private set; }


   2: //modifiers on both accessors not allowed.




Indexers cannot be defined using auto-implemented properties.



If you do so, you end up with compiler error





   1: //indexer property cannot be defined using short-hand notation


   2: public string this[int index]


   3: {


   4:             get; 


   5:             set;


   6: }


   7: /*Errors you would notice


   8: 'LinqBasics.Person.this[int].get' must declare a body because it is not marked 


   9: abstract, extern, or partial


  10: */




Automatically implemented properties must defined both get and set accessors.



The following is not valid.





   1: public string LastNameX { get; } 


   2: //missing set accessor, thus invalid.




Normal properties can be initialized, while auto-implemented properties cannot be initialized.



See the code below.





   1: //Normal properties can be initialized.


   2: private string _lastName = "Vangapandu";


   3: public string LastName{ get { return _lastName; }}


   4:  


   5: //Auto-implemented properties cannot be initialized.


   6: public string ZipCode { get; set; } = "30605";




The documentation also talks about creating immutable classes using auto-implemented properties. So, now lets make the Person class immutable (we make all the properties as read-only and privatize the constructor. also we provide a factory method for instantiation.)





   1: public sealed class Person


   2:     {


   3:         public string FirstName { get; private set; }


   4:         public string LastName { get; private set; }


   5:  


   6:         private Person()


   7:         {


   8:         }


   9:  


  10:         public static Person CreatePerson(string firstname, string lastname)


  11:         {


  12:             Person p = new Person();


  13:             p.FirstName = firstname;


  14:             p.LastName = lastname;


  15:             return p;


  16:         }


  17:     }




I will add more information later if required. I hope this article is as informative as I wanted it to be.

Tuesday, February 10, 2009

Long hiatus and queued up work … new ideas…

Well, its been a long time since I blogged something and it was just that I thought I had a legitimate reason for not to blog. I am attending this training at my work which is kick-ass (when it comes to learning) and wierd when it comes to knowledge being graded with quiz and exams. Anyway, I love the learning part and the exams – not much. But it is my full time job and I got to learn what they throw at me, which is fun though. Anyway, that training itself keeps me busy most of the day and most of the week. The time that I am left with, I spend it watching tv (did i mention I am actually following 7 different TV series and I am a huge fan of HOUSE). Anyway, I have once again began thinking about developing a reporting engine using Silverlight and WCF. We use LogiXML internally and it does a pretty good job with its flexible approach when it comes to integrating reports with existing software systems, but personally (this does not represent the opinion of my employer in any way) I feel it is too complex and we use only 10% of what the engine provides. Moreover it is darn-slow since it uses a lot of Datasets and writes whole bunch of XML files. I wish to revamp this, as a challenge to come up with a great Silverlight-based report front-end driven by WCF on the server. Apart from this pet project, I am working with a friend on a super cool application which is still in its infancy but hopefully things would be improved as I graduate from the training camp.

Lets talk about the reporting suite

1. Reports can be created simply by adding a query or a method from a .NET plugin.
2. Drill-Down reports can be developed by simply mapping the reports using a column pulled from the parent report.
3. Reports can be styled using standard silverlight styles.
4. Overall look would initially be fixed and as the application evolves, a designer can be used to restructure the components. Fine-grain design might not be supported yet, since it is complex to implement.
5. Reports can have input-data which should be easy to set up.
6. The reporting engine would support scheduling reports off the shelf.
7. Events would be raised on the server and plugins would be invoked for those events passing appropriate data. For example, BeforeReportLoads event would be fired as the report is being loaded and this would invoke IAsReportLoaded.ReportLoading(ReportInputData) would be called. So we can create a plugin which would be injected into the server and which provides implementation for the interface and in the implemented method, we could save the ReportInputData to a database. This is what we call “saving the user favorites”.
8. The report viewer would support generating graphs/charts on-the-fly and in the future, one would be able to save the chart parameters as a favorite and apply when required.
9. The report grid would be fancy one with support for grouping, sorting, filters and should be one like the Intersft Webgrid.

Cut the crap and talk about technical details

I may be wrong but I think the application should be using PRISM since it supports dynamic loading of XAP files (modules) which makes the application faster to load and better to use. Remember, not all users would use the entire application at once which makes dynamic injection of modules a great catch. PRISM also automatically makes my application to have a great design (I know it is not true but at least it makes me know what is the right way to do some things, if not all).

What else?

I am using FeedDaemon and let me tell you this – it is a great tool for avid blog reader like me and you. http://www.newsgator.com is the place that you should visit and download FeedDaemon and use it, you would not repent. By the way, I figured out how to make datagrid (in WPF) display drill-down data. (drill-down reports using WPF datagrid, I would post more on this later).