Thursday, November 29, 2007

DLR Pad on CodePlex

Finally I have uploaded my DLR Pad application on CodePlex. I have delayed the upload due to two main reasons. First was the new version of Bookvar that we shipped yesterday (unfortunately the final code of the DLR Pad is not yet integrated into Bookvar, but this will happen in the next release). The second reason is that I wanted to refactor some of the code and make provider model for the available languages.

Show me your DLR language

As you just read DLR Pad now has a provider based architecture that will allow any DLR language to be added on the fly. What you need to do is just to write a new DynamicLanguneEngine implementation and override a single property that returns the appropriate ScriptEngine. For example here is the IronPython's implementation:

internal class IronPythonLanguageEngine : DynamicLanguageEngine

{

    public override ScriptEngine ScriptEngine

    {

        get { return PythonEngine.CurrentEngine; }

    }

}

Also you will need edit the config file to add your language implementation:

<add

    name="IronPython" description="IronPython engine."

    languageShortName="ipy"

    type="Avaxo.Scripting.IronPythonLanguageEngine, Avaxo.Scripting" />

For now only IronPython and IronRuby are added by default. However if you want you can register some other language - for example IronScheme (IronLisp) or Smalltalk. In the future when VBX and the new managed JavaScript implementation become available they can also be added to the DLR Pad.

Feel free to download DLR Pad and have fun with it. In my next post I will show you how go wild with it.

I want to say one more thing here.

CodePlex & SvnBridge rocks!

I have been using CodePlex previously for my InfoCardControl. As you may know CodePlex is using TFS to hold the source code. Till recently the most appropriate way to check-in source code was the Team Explorer extension for Visual Studio. Unfortunately I have uninstalled VS 2005 along with the Team Explorer and start to use VS 2008 only. So I have to install Team Explorer this time for VS 2008. And oh man its file size is 387 MB. So while downloading I decided to try the SvnBridge developed by the guys from CodePlex. And magically it worked. The tool is only 427 KB and basically sits between your local svn versioned files and remote TFS. Every svn operation you execute gets it mimic into TFS one. Combined with TortoiseSVN and you are ready to go to space :) I encourage anyone to try SVN Update DLR Pad for himself to see the SvnBridge in action.

That's it for now. Stay tuned as I will show you how to do crazy stuff with DLR Pad.

P.S.: Any comment about the code is welcome and encouraged.

kick it on DotNetKicks.com

Sunday, November 18, 2007

DLR Pad - interactive programming with XAML and DLR

This post is about a tool that I have build. It is called DLR Pad. In one sentence it allows you to rapidly create simple XAML based applications and script against them with dynamic language of your choice. DLR Pad was in my head for quite some time, but recently I had enough time to implement it. Let me explain how I came up with the idea.

Idea

As you maybe already know this summer I have been to Korea to participate in this year's Imagine Cup competition. Our team have build a mind mapping application - Bookvar. We believe that Bookvar is the next generation mind mapping tool. I encourage you to go there, download the application and send us your feedback; we are listening. In order to win the competition we tried to use all the latest Microsoft technologies. Unfortunately we did not qualify for the final round. Now a couple of months later we are highly motivated to make Bookvar a real product.

DLR - Dynamic Language Runtime

One of the technologies we have used in Bookvar is DLR - Dynamic Language Runtime. DLR is a set of classes and services that allow building of high performance dynamic languages on top of CLR. The beauty of DLR is both the common type system that is shared between all language implementations and in the .NET integration itself as well. This means that you can access the whole .NET Framework. Right now Microsoft is in process of implementing two languages on top of it - Python and Ruby, called IronPython and IronRuby. Both of them are pure open source projects and can be downloaded from here - IronPython, IronRuby. If you want to wake up your inner sleeping language geek I encourage you to check them out (IronRuby even accepts external contributions).

We have used DLR to create an interactive programming environment (Bookvar console) for interacting with our mind mapping model. You can check demo of it in this Channel 8 video. The code for the console is based on the DLRConsole sample here.

After the competition I wanted to extend the Bookvar console so that I can define XAML objects (similar to XAMLPad) and write code against them in one of DLR languages. This is how DLR Pad was born.

DLR Pad

Let's look at the main window of the app:

DlrPadMain

At the top left you can see the interactive console. It will be our coding sandbox. On the right is the rendered XAML content. The XAML itself is defined in big text box in the bottom. In our case we have a simple button called 'button'. What is cool about it is that we can access the button in the console window using its name. For example we can change the button's text using this snippet of code:

button.Content = "Hello"

Actually we are using IronPython here. Note that when you type the '.' you will get an IntelliSense window that will list all available members on the Button type. Unfortunately the IntelliSense works only in IronPython. IronRuby is still in pre-alpha release so only part of the features are implemented right now.

DlrPadIntelliSense

Adding event handler to the button

Let's examine more complex scenario - adding click event handler to the button.

IronPython way
Here is the python code to do this:

def handle(*args) : button.Content = "IronPython"
button.Click += handle

DlrPadIPHandle

IronRuby way
Here is the ruby equivalent to the same operation:

button.click { button.Content = "IronRuby" }

DlrPadIRHandle

Note: In order to start coding in IronRuby you should pick it up from the combo in the upper left corner.

Each object that you defined in your XAML that has a Name (x:Name) automatically is available in the console window.

What's next?

I'm in the process of setup the code on CodePlex here. The console has some bugs that I'm aware of. I also have some ideas how to expand the application in the future - ability to load and use custom assemblies and other interesting stuff. Your feedback and suggestions are welcome as well.

Download

Start experimenting and having fun with DLR Pad by downloading it from here.

Hope you will find the tool useful.

Saturday, November 3, 2007

CanYou? - sample Facebook application

[Update: The source can now be found here. It has been updated to use the latest version of FacebookNET library.]

As you can read from my previous post I have been invited to give a presentation about ASP.NET at Computer Space event. I have picked up the idea about building a Facebook application with ASP.NET. And here it is. It is called "Can You?". Let me explain you the idea behind it.

The Idea

The idea of the app is to utilize your social graph and search through all your friends in order to check can you do particular activity. For example you may want to stay for a couple of nights in France and want to see if some of your friends can help you. The idea is simple and silly, but can be expanded to have more potential if your friends also add the application. Then searching for appropriate connections can be expanded on their friends too. (Note that Facebook did not allow you to recursively get friends of your friends. Only one level down from the currently logged user). You can install the app to your Facebook account from here.

Development of the Idea

I have previously mentioned that there are 2 libraries for building Facebook applications with .NET - Facebook.NET and Facebook Developer Toolkit. The first one is build by no other but Nikhil Kothari, the second by Clarity Consulting. So which to use? Without a doubt the Facebook.NET is the way to go. It has some pretty good server controls that abstract away some of the Facebook plumbing. I'm not going to explain in details Facebook.NET, nor the ways you can build apps for Facebook. You can learn all this in Nikhil's introduction to Facebook.NET post. I encourage you to read it right away. Next time it is best to come to my presentation :)

Now I will focus on the application and how I utilize the library.

Activity Provider

As you have already learned about the idea and probably played with the app let me explain you the implementation details. The application is build on the idea of Activity Providers. Each activity provider holds details about specific activity that the user will be able to do - for example going to foreign country or working at some company. The Activity Provider is based on the provider model introduced in .NET 2.0 and all available activities are picked from the configuration file. Each activity provider must implement:

public abstract ActivityControl GetActivityControl(Page page);

which returns an instance of ActivityControl.

ActivityControl

ActivityControl is very simple. It derives from user control and have a simple event called ActivitySelected defined this way:

public event EventHandler<ActivitySelectedEventArgs> ActivitySelected

ActivitySelectedEventArgs

The event arguments for the ActivitySelected event is simple class that holds the ids of the users which are appropriate (match the condition) for the selected activity.

public class ActivitySelectedEventArgs : EventArgs

{

private readonly List<string> appropriateUids;

public IList<string> AppropriateUids

{

get { return appropriateUids; }

}

public ActivitySelectedEventArgs(IEnumerable<string> appropriateUids)

{

this.appropriateUids = new List<string>(appropriateUids);

}

}

These arguments are then used on the default.aspx page to display the list of friends that can do the work. Let's look at the Default.aspx page.

Default page

In the default page we have a drop down with all available activities. We populate it using a helper class that retrieves them from the configuration file. When an activity is selected we load its ActivityControl in a PlaceHolder. Then when the ActivitySelected event is rose we have a ListView (new class in 3.5 that provides complete control over on the generated markup, something like repeater on steroids; more details for it on ScottGu's blog) that we bind with the appropriate friends. That's it. I would not paste any code or markup. You can look at them in the sample solution.

Now let's examine the two activities that I have created.

Country Activity

This is activity for visiting a foreign country. Let's look at the code and let me explain you what it does:

List<string> appropriateUids = new List<string>();

string selectedCountry = ddlCountries.SelectedValue;

FacebookApplication fbApp = FacebookApplication.GetCurrent(Page);

object queryResults = fbApp.Service.Fql.ExecuteQuery(

string.Format(

@" SELECT uid, hometown_location.country

FROM user

WHERE uid in (

SELECT uid2

FROM friend

WHERE uid1={0}

)",

fbApp.UserID));

foreach (object result in (IEnumerable)queryResults)

{

string country = DataBinder.Eval(result, "hometown_location.country").ToString();

if ( country.Equals( selectedCountry, StringComparison.OrdinalIgnoreCase ) )

{

appropriateUids.Add(DataBinder.Eval(result, "uid").ToString());

}

}

OnActivitySelected(new ActivitySelectedEventArgs(appropriateUids));

First we get the current FacebookApplication object (same technique is used for getting ScriptManager for example). The FacebookApplication is headstone for accessing the Facebook API. Using it we are able to execute FQL (Facebook's SQL like DSL for making queries and return particular projections of the data. This ends up in less traffic and backend parsing) which gets the id and country of all friends of the currently logged user. Then we iterate over the results and check for appropriate data. Have a closer look how we access the results. What Facebook API returns from a FQL query is just a collection of property bags (JSON objects). To handle them Facebook.NET implementation creates an instances of its own internal object:

internal sealed class JsonObject : Hashtable, ICustomTypeDescriptor

As you can see it implements ICustomTypeDescriptor, which provides runtime information about object's properties, methods, etc. This is way we are using the DataBinder.Eval() method to get the required data. In our case this is the country(Note that we can specify the country in a where clause in the FQL).

Work Activity

This one check's whether some of your friends is working in particular company so they can help you work there too.

LINQ sourceI'm posting a screenshot here, because my code highlighting tools breaks on LINQ queries :) As you can see from it here we are using LINQ this time to find did anyone of our friends have ever worked at the selected company. This query will pull the all fields data about the friends. This can be optimized using the second parameter passed to GetUsers() method. It specifies which particular fields you want to be retrieved.

So that's it. You can look at the sample and try to build your own activity that can be plugged into the application.

Download materials

Here is the link to the source code. It has a little bug I'm sure you will find it :) Note that I'm including the source to Facebook.NET, because I have found a small bug in the code and have to fix it.

Presentation is available here. It is in the form of mind map. You have to download and install Bookvar in order to open it.

You can also look at the presentation in our Silverlight based mind map viewer here.

P.S.: Unfortunately I had some problems with the hosting facilities and the application that is uploaded to the server is build on ASP.NET 2.0 and did not have the AJAX stuff I have originally added to the application.

P.S.S.: You can also listen to this .NET Rocks! podcast with Nikhil Kothari talking about Facebook.NET, Script#, life, etc.