Showing posts with label dynamic. Show all posts
Showing posts with label dynamic. Show all posts

Sunday, June 12, 2011

NDC 2011

Last week some colleagues and I went to the NDC conference in Norway.



Apart from the weather, which was crappy, it was an awesome conference. I've seen some great talks and am looking forward to watching some of the talks I missed (because I was in another session) online. I also went home with some new great ideas for books I want to read:

  • Introducing HTML 5, by Bruce Lawson and Remy Sharp. They gave the HTML 5 talks during the second day of the conference in a small and very crowded room. They convinced me even more of the amazing things you can do for web pages with the new upcoming standard. It was a relieve as well to hear someone from the Opera browser team talking about HTML 5 instead of the standard Microsoft talks I heard thus far. 
  • Test-Driven JavaScript Development, by Christian Johansen. Too bad his talk was given simultaneously with Rob Ashton's (Document databases with ASP.NET MVC), Kevlin Henney and Anders NorĂ¥s's (Introducing The FLUID Principles) and Hadi Hariri's (Dynamic in a Static World). I went to this last session, which was very good. It gave me some ideas and examples of more things I can start doing with dynamic. I would really like to try to get a DSL written with it (I would probably start off by copying a Ruby example, since it is not easy stuff). The talk about the FLUID principles was very good as well, my colleagues went to that one and it is one of the talks to catch on rerun, once they put the videos up. I did follow the talk about the SOLID principles, which was nice to refresh again. I went to the RavenDB by Example talk on day  3 of the conference. It was a good thing the speaker also mentioned some of the problems he had with a document database, having to rethink the design of your data as opposed to relational databases.
  • The Joy of Closure, by Michael Fogus and Chris Houser. I didn't get to catch any of the Closure and F# talks and it would be nice to get up to speed with this. Also something to watch on rerun and see what we can do with it
  • 97 Things Every Programmer Should Know, by Kevlin Henney and 97 Things Every Software Architect Should Know, by Richard Monson-Haefel. I only went to Kevlin's talk about the 101 things he learned in architecture school, which was light, but enlighting. His other two talks apparently were very good as well, as my colleague went to those.
  • Specification By Example, by Gojko Adzic. His talk wasn't so good, but I think a lot can be learned from this book. One thing I will really remember from the conference is the multiple question marks that speakers had with BDD, DDD and agile. While they are all good techniques, they have their flaws and the software community really needs to figure out how we can do these things even better. Gojko's post on his blog about one of these talks really explains the problem a bit as well. He also mentioned our Cronos colleagues from iLean in his talk, which I think was pretty cool. And he is also one of the creators of cuke4ninja, a port of cucumber for .Net.


Apart from those books and talks I already mentioned, I also followed some of the talks on mobile development. The ones about multi platform development were really informative. The MonoTouch and MonoDroid projects have moved from Novell to Xamarin and are planning on a next release in the coming months. Biggest take-away there was: use the latest MonoTouch and MonoDroid builds for now and switch to the Xamarin builds once they are published. Jonas Follesoe's talk on this topic was great, if you're doing mobile, catch it on rerun! 

I also really liked the AOP talks given by the PostSharp people. They have a great framework for doing AOP, which is really powerfull and which gives you a lot of cool features for keeping your code nice and, well, sharp. They also mentioned some other AOP frameworks, which I think is a nice gesture, since they are not the only ones out there.

The CQRS talk by Fredrik Kalseth was inspiring as well, although he only mentioned one part of CQRS. It was explained really well and can be used as a basis on future projects. I also learned in his talk that JetBrains have a Ruby IDE which I didn't know about. As I look at their site now, I see they're also working on an Objective-C IDE. 



So, all in all, a very good conference, which I hope to catch again next year, and hopefully without the rain. I learned a lot and have now a whole lot of stuff to read and learn even more about. Too bad there's only 24 hours in a day (of which I really need 9 to sleep, since I'm a sleepy head).

Thanks as well to my colleague, Guy, for providing some very nice pictures. You can find the entire collection here.

Monday, June 6, 2011

More on DynamicObject: TryInvokeMember

I just came along another old example of DynamicObject, I would like to share with the world.

What I didn't mention in my last post is that DynamicObject has more methods you can override besides TryGetMember and TrySetMember. These two are very useful when working with properties you want to add on the fly. For methods the TryInvokeMember is a better choice to override. This method will get called on your DynamicObject when it can't resolve a method call.

Let's for instance write a very simple dynamic tracer class. First of all I will inherit again from DynamicObject. This time the class I am creating, DynamicTracer, will not hold an XML tree, but it will wrap another object.

Every time a method is called on this object we will print out (hence the name DynamicTracer) the operation that is being called.

 class DynamicTracer : DynamicObject 
 { 
   object theObject; 
   public DynamicTracer(object theObject) 
   { 
     this.theObject = theObject; 
   } 
   public override bool TryInvokeMember(InvokeMemberBinder binder, 
      object[] args, out object result) 
   { 
     try 
     { 
       Console.WriteLine("Invoking {0} on {1}", binder.Name, 
            theObject.ToString()); 
       Type objectType = theObject.GetType(); 
       result = objectType.InvokeMember(binder.Name, 
            System.Reflection.BindingFlags.InvokeMethod, null, 
            theObject, args); 
       return true; 
     } 
     catch 
     { 
       Console.WriteLine("Oops, cannot resolve {0} to {1}", 
            binder.Name, theObject.ToString()); 
       result = null; 
       return false; 
     } 
     return true;
   } 
 }  

The usage is quite similar to using TryGetMember and TrySetMember, only now are we getting a InvokeMemberBinder as parameter, together with the argument list that is being used and an out parameter for returning the result. I use reflection to invoke the method on the actual object.

To use this tracer, the only thing you need to do is wrap an object with it:

 FileInfo fi = new FileInfo("c:\\temp\\test.txt"); 
 dynamic tracedFI = new DynamicTracer(fi); 
 tracedFI.Create();  

When Create is called, there will be no matching method found in the DynamicTracer class, which will instead trigger the TryInvokeMember method. Although this seems pretty cool and useful, beware you loose all auto completion on any object you wrap this way, which is, for all things dynamic, a downside.

Doing the dynamic thing (Part V)

This will be the fifth and last part in this series. I will try and post some additional stuff concerning dynamic programming, but they will be standalone posts and will not be part of this series (the numbering is getting a bit out of hand).

In last post, you saw how to use the ExpandoObject. We will extend this now with the DynamicObject class. The difference between the ExpandoObject and the DynamicObject is that the first one gives you the ability to create dynamic types on the fly, with custom added properties, methods, ... for each object you create. The DynamicObject class however gives you the opportunity to extend the basic behaviour(s) you want your dynamic objects to have. You can also add some logic for adding dynamic behaviour.

You create your own dynamic objects by inheriting from DynamicObject. You can add extra methods to this class and you can override existing methods of the base class. it is by overriding the existing methods that you actually give your objects dynamic behaviour.

I will give you a practical example of this. A while back a colleague of mine was writing a Silverlight dashboard application on top of a TFS server, using the TFS APIs. This implied writing a WCF service the Silverlight application could use for quering the TFS server. Now, while the TFS APIs are quite extensive, they don't implement the ISerializable interface for all data type objects.

Facing this problem, my colleague started writing DTO classes for all of these types that weren't serializable. But I started thinking if it wasn't possible to just leverage the intrinsic capabilities of dynamic objects. After all, the only thing needed for these TFS objects to be send from and to the service were methods to serialize them to and from XML. And why not make these objects dynamic on the client side, hence excluding the need for referencing or redefining all these TFS objects on the server and client side.

First thing I needed for this, was a way to get any object on the server side serialized to XML. For this I will use the DynamicObject class. I want to be able to use my DynamicObject the same way I used the ExpandoObject class, by adding properties as needed. The DynamicObject for this has two important methods an inheriting class can override. These methods are TryGetMember and TrySetMember. The TryGetMember method gets called whenever you are accessing a property or method of your DynamicObject. The TrySetMember method gets called whenever you want to assign a value to a property or method of your DynamicObject.

I will explain this in more detail for you in a bit. I will start by getting information from our TFS server. I use a simple query and a couple of foreach loops to get information about all workitems in a certain project.

 TeamFoundationServer tfsServer = 
     new TeamFoundationServer("http://serverurl"); 
 WorkItemStore store = 
     (WorkItemStore) tfsServer.GetService(typeof (WorkItemStore)); 
 foreach (Project project in store.Projects) 
 { 
   foreach (WorkItemType wit in project.WorkItemTypes) 
   { 
     WorkItem theItem = new WorkItem(wit); 
     //dynamic code coming up 
   } 
 }  
Once I have a WorkItem from TFS, I want to be able to build a new DynamicObject, using it the same way as an ExpandoObject, adding properties as I go along.

 dynamic dyn = new DynamicElement(theItem.ToString()); 
 dyn.ChangedDate = theItem.ChangedDate.ToString(); 
 dyn.ChangedBy = theItem.ChangedBy; 
 dyn.Description = theItem.Description;  

The DynamicElement class is the class I have inherit from DynamicObject. It is this class that contains the TryGetMember and TrySetMember overrides. Every time I dynamically add a property to my DynamicElement object (like I do for ChangedDate, ChangedBy and Desciption in the example above), the TrySetMember override gets called. In this override I create a sort of dictionary of all the property names and property values the user of DynamicElement has thus far added. This is actually quite similar to what an ExpandoObject does out of the box. The difference is that I can now choose how I store these dynamically added properties and instead of using a dictionary, I use an XElement. I know I have to be able to serialize the entire object to XML, so better make my life simple.
Here you see part of the DynamicElement class that inherits from DynamicObject.
 public class DynamicElement : DynamicObject 
 { 
   public XElement actualElement; 
   public DynamicElement() 
   { } 
   public DynamicElement(XName name) 
   { 
     this.actualElement = new XElement(name); 
   } 
   public override bool TrySetMember(SetMemberBinder binder, object value) 
   { 
     string name = binder.Name; 
     if (actualElement == null) 
     { 
       actualElement = new XElement(binder.Name); 
       return true; 
     } 
     actualElement.Add(new XElement(name, 
       value)); 
     return true; 
   } 
   public override string ToString() 
   { 
     return actualElement.ToString(); //actualElement.Value; 
   } 
 }  
You can see I use an XElement datamember, which I use to build the XML to return from a WCF service call (I didn't make the datamember private, to keep the example short, I need access to it, later on in the example, you should never do this in real life). I also have a constructor overload I can use to set the root name of the XElement. The TrySetMember does nothing more than building the XML. The SetMemberBinder parameter can be used to see which property (or method) names the user of your DynamicElement used (in this example ChangedDate, ChangedBy and Desciption). Once the XML is build, the ToString method can be used to serialize the entire object to XML.
In using this DynamicElement for my WorkItems, I also want to add project info to them:

 dynamic dyn = new DynamicElement(theItem.ToString()); 
 dyn.ChangedDate = theItem.ChangedDate.ToString(); 
 dyn.ChangedBy = theItem.ChangedBy; 
 dyn.Description = theItem.Description; 
 dynamic dynProj = new DynamicElement("Project"); 
 dynProj.Name = theItem.Project.Name; 
 dynProj.Id = theItem.Project.Id; 
 dyn.Project = dynProj.actualElement.Descendants(); 
 return dyn.ToString();  

For the project I use a second DynamicElement. Once the project element is build, I add the entire XML tree to a new Project property of the dynamic workitem object. Eventually I call the ToString method which serializes the object to XML. This way of working makes my service methods quite simple.

 [ServiceContract] 
 public interface IService1 
 { 
   [OperationContract] 
   string GetWorkItem(); 
 }  

So far for the server side of things. We still need a client that can parse the generated XML. For this, again, I will use a DynaimcElement (actually the same one as above, but with extra code added). First of all the incoming XML needs to be understood. A simple solution for this is adding an extra constructor to our DynamicElement class that takes a XElement as a parameter (being the entire XML tree).

 public DynamicElement(XElement actualElement) 
 { 
   this.actualElement = actualElement; 
 }  

Every time now the code wants the value of one of the properties, the TryGetMember override of DynamicObject gets called, so lets add this.

 public override bool TryGetMember(GetMemberBinder binder, 
   out object result) 
 { 
   string name = binder.Name; 
   var elements = actualElement.Elements(name); 
   int numElements = elements.Count(); 
   if (numElements == 0) 
     return base.TryGetMember(binder, out result); 
   if (numElements == 1) 
   { 
     result = new DynamicElement(elements.First()); 
     return true; 
   } 
   
   return false; 
 }  

The code again uses the Name property of the GetMemberBinder, which gives us the name of the property we are trying to get the value of. Next we look for an element with this name in the XML tree. If we can't find this element, maybe the base class can find it (which it probably won't). If we find 1 element with this name, we return it as a DynamicElement. This way we can use the ToString method on it, which will return the Value of this element, and we can also dot further into subproperties of the object (eg. for the Project property of a workitem). We can now write source code like this:
 TFSService.Service1Client client = new TFSService.Service1Client(); 
 string result = client.GetWorkItem(); 
 dynamic workitem = new DynamicElement(XElement.Parse(result)); 
 Console.WriteLine(workitem.ChangedDate); 
 Console.WriteLine(workitem.ChangedBy); 
 Console.WriteLine(workitem.Description); 
 dynamic project = workitem.Project; 
 Console.WriteLine(project.Name);  
I can also add code to the service to return some random XML. I added another service method for this.

 public string GetSomeXml() 
 { 
   return "<test><child1>firstchild</child1>
    <child2>secondchild</child2><child3>
    <sub1>firstsub</sub1><sub2>decondsub</sub2>
    </child3></test>";  
 }  
The client can also print out the values of this XML:

 result = client.GetSomeXml(); 
 dynamic someXml = new DynamicElement(XElement.Parse(result)); 
 Console.WriteLine(someXml.child1); 
 Console.WriteLine(someXml.child2); 
 Console.WriteLine(someXml.child3); 
 Console.WriteLine(someXml.child3.sub1); 
 Console.WriteLine(someXml.child3.sub2);  
This way it is quite easy to build objects on both client and server without the need to provide classes for each one of them. You just take the 'one time effort' to write up a DynamicObject class and you are done.

What I still want to test with this code, is whether it is possible to get this code working together with a tool like AutoMapper (on the server side). It is just a bit cumbersome to copy over all the values of your dynamic objects.

At least I hope this gives you an idea of a practical use of dynamic objects in .Net. It is not the most obvious example and I expect most uses of dynamic lie in working together with COM and JavaScript for SilverLight applications. Other than that I haven't seen many practical examples popping up on the Internet (except for this one, of course).

Thursday, April 28, 2011

Doing the dynamic thing (Part IV)

This is already the fourth part in this series (for the full story, see posts 1, 2 and 3). And as promised, I'm going to do something a bit more advanced in this post. I will introduce you to the ExpandoObject and, in a fifth post, the DynamicObject classes. They bring you new opportunities for dynamically expanding your code, hence the term EXPANDOObject. Something you can, for instance also do in dynamic languages like Ruby (in one of the next posts I will show you some IronRuby code).

The ExpandoObject can be found in de System.Dynamic namespace (system.core.dll) and is actually a kind of key value set of keys (names) and implementations for these keys. These implementations can be fields, methods, properties, delegates, ... The funky thing is, you can add these implementations at runtime. You can start of with an ExpandoObject with no functionality at all and you can add functionality as you go.  The following line of code gives you an empty ExpandoObject:
dynamic sampleObject = new ExpandoObject();

Adding a property is as simple as:
sampleObject.test = "Dynamic Property"; //I now have a property 'test'
Console.WriteLine(sampleObject.test);
Console.WriteLine(sampleObject.test.GetType());

You can also add methods at runtime:
sampleObject.number = 10;
sampleObject.Increment = (Action)(() => { sampleObject.number++; });

// Before calling the Increment method.
Console.WriteLine(sampleObject.number);

sampleObject.Increment();

// After calling the Increment method.
Console.WriteLine(sampleObject.number);

This will print 10 and 11 to the console respectively.
It is also possible to add events at runtime:
sampleObject.sampleEvent = null;

// Add an event handler.
sampleObject.sampleEvent += new EventHandler(SampleHandler);

// Raise an event for testing purposes.
sampleObject.sampleEvent(sampleObject, new EventArgs());

Besides this dynamically adding of functionality, the ExpandoObject is actually nothing more than a fancy key value set. It actually implements the IDictionary interface, which means you can enumerate all members you have just added.
Console.WriteLine("sampleobject: ");
foreach (var property in (IDictionary<String, Object>)sampleObject)
{
    Console.WriteLine(property.Key + ": " + property.Value);
}
        }

        // Event handler.
        static void SampleHandler(object sender, EventArgs e)
        {
            Console.WriteLine("SampleHandler for {0} event", sender);
        }
    }
}
The above program will give you the following output:

Now, this is where most examples on ExpandoObject stop. It explains the use of the class, and that's it. On the other hand, this is where I start thinking, ok, cool, but what's the use? I mean, how can I use this dynamic run time behaviour in my everyday coding life. For this, in my opinion, the ExpandoObject runs a little short. The fact that an ExpandoObject is actually nothing more than a fancy dictionary means you can also add functionality through this dictionary, but this is a little pain staking, so I will not go into this. You will, however, get more practical use out of the DynamicObject class, which I will explain in the next post on this subject.

Monday, April 4, 2011

Doing the dynamic thing (Part III)

In the first part of this series I gave an introduction to what the dynamic keyword can do for you. The second part of this series showed you how this dynamic keyword can be pretty handy when interoperating with javaScript code. in this third part we will look into interoperating with Excel. This part will be brief, though, mainly because there are already quite a lot of examples to be found concerning this subject.
In this post I will extend the example I started in the previous post. There, we've seen I get a list of Person data from a WCF service. This Person list is shown in a DataGrid control of a Silverlight application. The latest version of Silverlight, supports running out of browser and once you run out of browser you get some extra possibilities for your application. One of these possibilities is interacting with automation objects, like Excel. So, let's extend our example so it can run out of browser and also, so it can generate an Excel document.
Running out of browser is actually not that hard to do. The user of your application can right click on the Silverlight application and choose 'Install NameOfYourApplication onto this computer'.


To offer this right click functionality to your users you need to check the 'Enable running application out of the browser' checkbox in the project settings of your Silverlight application.


The button control under this checkbox will show a popup window with some extra settings. One of these extra settings, 'require elevated trust', is important if you want to offer automation functionalities in your out of browser Silverlight application, so you should check this as well. 


Once you have done this, your users can install your application. 
In code it is possible to test whether or not you are running out of browser. I, for instance, added some code to disable a button that generates HTML if we are running out of browser, since generating HTML is pretty useless if you're not running in a browser window (and if you do execute the generation of HTML out of browser you will get a runtime error, so better disable it).
btnHTML.IsEnabled = !Application.Current.IsRunningOutOfBrowser;

We can also test whether or not we can use the automation capabilities.
if (AutomationFactory.IsAvailable)

Once we know we have automation available, we can create a new Excel object. The return type of the GetObject and CreateObject calls is dynamic, so this is a good choice for the type of your variable.
dynamic ExcelApp;
try
{
    ExcelApp = AutomationFactory.GetObject("Excel.Application");
}
catch (Exception exc)
{
    try
    {
        ExcelApp = AutomationFactory.CreateObject("Excel.Application");
    }
    catch (Exception exc2)
    {
        txtStatus.Text = exc2.Message;
        return;
    }
}

The reason I use both GetObject and CreateObject is that if Excel is already running, we can get a reference to the application with GetObject. If Excel is not already running, we need to start, or create the application with CreateObject.
Once we have the Excel application at our disposal, we can create workbooks, we can add data to cells, etc. The good news is that, since version 4.0 of the .NET framework all objects in Excel (and in the other Office automation frameworks) are of type dynamic. This simply means you can omit a lot of casting operators. Where previously you needed to write code like this:
var ExcelApp = new Excel.Application();
ExcelApp.Visible = true;
Workbook workbook = ExcelApp.Workbooks.Add();
int rowCounter = 1;
foreach (DataService.Person p in dataGrid1.ItemsSource)
{
    ((Range)((Worksheet)workbook.Sheets[1]).Cells[rowCounter, 1]).Value = p.FirstName;
    ((Range)((Worksheet)workbook.Sheets[1]).Cells[rowCounter, 2]).Value = p.LastName;
    rowCounter++;
}
((Range)((Worksheet)workbook.Sheets[1]).Columns[1]).AutoFit();
((Range)((Worksheet)workbook.Sheets[1]).Columns[2]).AutoFit();

You can now write this much more briefly like this:
ExcelApp.Visible = true;
dynamic workbook = ExcelApp.Workbooks.Add();
int rowCounter = 1;
foreach (DataService.Person p in dataGrid1.ItemsSource)
{
    workbook.Sheets[1].Cells[rowCounter, 1].Value = p.FirstName;
    workbook.Sheets[1].Cells[rowCounter, 2].Value = p.LastName;
    rowCounter++;
}
workbook.Sheets[1].Columns[1].AutoFit();
workbook.Sheets[1].Columns[2].AutoFit();

As you can see, there is a lot of casting going on in the first example, primarily to the Worksheet type and to the Range type. This is something we can completely omit when using dynamic. Which, in my opinion is a good thing!
The bad news, however, is, that with these dynamic types, your intellisense is gone. You need to know which operation calls are valid on which objects. But than again, who cares, because previously you needed to know which type you needed to cast to. If you got that one wrong, you'd get a runtime exception as well.
If you want to know even more on automation, this article in the MSDN library can give you some extra info.
That's it for the Office automation part of this series. Be ready to do some serious stuff with ExpandoObjects in the next post.

Sunday, April 3, 2011

Doing the dynamic thing (Part II)

After the basic intro given in the first part of this series, it is time for something more advanced. It won’t be rocket science, yet, but you will get more insight into what dynamic coding can do for you.
As mentioned in the previous post, dynamic programming can help you a lot when working with COM objects. I will give an example of this for JavaScript objects in a small Silverlight application. In the next post I will extend this simple example and I will explain interaction with Excel. But first, let’s talk about JavaScript.
Interacting with JavaScript might be something you need in real life. For instance if you have a Silverlight app that is hosted on a page that relies on JQuery a lot. JQuery can provide you with objects your SilverLight application does not know about. How can you interact with these objects if your managed code doesn’t know their type? The answer is to utilize dynamic.
To illustrate this, suppose we have a service running that can give us data about persons. A Person being just a DTO class with a FirstName and LastName property. Plain and simple.

[ServiceContract]
public interface IDataService
{
    [OperationContract]
    List<Person> GetData();
}
 
[DataContract]
public class Person
{
    [DataMember]
    public string FirstName { getset; }
    [DataMember]
    public string LastName { getset; }
}

I also have a HTML page that includes a SuperPerson object. A SuperPerson being the same as a Person, but with one extra property, 'somethingextra'.
function SuperPerson(firstname, lastname, somethingextra)
{
    this.firstname = firstname;
    this.lastname = lastname;
    this.somethingextra = somethingextra; 
}
There is also a JavaScript function that can create one of these SuperPerson objects with the extra data.
function GetSuperPerson(firstname, lastname, somethingextra) {
    var person = new SuperPerson(firstname, lastname, somethingextra);
    return person; 
}
To illustrate how to work with such a JavaScript object, I’ve made a small Silverlight application that receives a list of person objects from the WCF service described above. The Silverlight application will display this list of persons in a DataGrid control. 
public MainPage()
{
    InitializeComponent();
    DataService.DataServiceClient client = new DataService.DataServiceClient();
    client.GetDataCompleted += new EventHandler<DataService.GetDataCompletedEventArgs>(client_GetDataCompleted);
    client.GetDataAsync();
}
 
void client_GetDataCompleted(object sender, DataService.GetDataCompletedEventArgs e)
{
    dataGrid1.ItemsSource = e.Result;
}
This is the basic set up I will use in this example. The Silverlight application will be hosted on an HTML page that has the above mentioned JavaScript code present. 
In this example, to keep it simple, I will build a HTML table. It will be the Silverlight code that builds this table, not the JavaScript code. For this, first thing will be to get hold of a specific div tag on the HTML page in which we will build our table. Silverlight lets you interact with the hosting page through the HtmlPage class. This class gives you a Document property that behaves pretty much the same as the document object in JavaScript, which makes it very easy to use.

HtmlElement theDiv = HtmlPage.Document.GetElementById("dynamicDiv");
HtmlElement table = HtmlPage.Document.CreateElement("table");
Next, we will iterate over all Person objects in the DataGrid.

foreach (DataService.Person p in dataGrid1.ItemsSource)
{
For each of these Person objects we will execute the GetSuperPerson function, present in the JavaScript of the hosting page. Since the Silverlight application has no knowledge of the SuperPerson type, we will use the capabilities of .NET 4.0.

    dynamic superperson = HtmlPage.Window.Invoke("GetSuperPerson", p.FirstName, p.LastName, System.DateTime.Now.Millisecond);
With the dynamic keyword in place our compiler does not complain about the SuperPerson type it does not know about. And since we know a SuperPerson has a firstname, lastname and somethingextra, we can interact with it though these operations with no problem.

    HtmlElement row = HtmlPage.Document.CreateElement("tr");
    dynamic td = HtmlPage.Document.CreateElement("td");
    td.innerHTML = superperson.firstname;
    row.AppendChild(td);
    td = HtmlPage.Document.CreateElement("td");
    td.innerHTML = superperson.lastname;
    row.AppendChild(td);
    td = HtmlPage.Document.CreateElement("td");
    td.innerHTML = superperson.somethingextra;
    row.AppendChild(td);
    table.AppendChild(row);
}
 
theDiv.AppendChild(table);
Two things are notable about the code above. First of all, I use firstname and lastname, not FirstName and LastName (mind the casing). This is because we are interacting with the JavaScript object, not with the original Person object. I purposely used other casing in the JavaScript code to make my point on this clear.
A second thing you may have noticed is a second use of the dynamic keyword. When I create a new td element, I do not use the HtmlElement type (which is valid for a td tag), but instead I use the dynamic keyword. I do this because I know for sure it is possible to call the innerHtml operation on a td tag. The HtmlElement, however, does not have this operation present (you can check this in your intellisense). There is also no specific type for a td element that does have this operation present. With dynamic there is no problem at all to call innerHtml, not at compile time and not at run time.
There you have it, two good reasons to use dynamic when you're interacting with JavaScript. You can get around unknown objects in managed code and you can call operations managed code has no clue of.
Be ready for the next two parts, first on dynamic and Excel and next about ExpandoObjects (this is where the fun begins!).

Thursday, March 31, 2011

Doing the dynamic thing (Part I)

A while ago I was asked to give a presentation to co-workers about the new features in the 4.0 .Net framework. Being a bit of a language geek, this job, of course, was cut out for me. A lot of topics passed the revue, but the most interesting one, in my eyes, was the new dynamic keyword and the new dynamic features in version 4.0 of the framework.

However it's a bit sad that, when searching the web for good examples of dynamic programming, you get so few practical answers. Most sites stay on the surface of really discussing dynamics and how they can be employed in real life problems. Also, most blog posts about the topic were made 2 to 3 years ago. I'm guessing that means dynamics didn't really kick in as expected. Why, you would ask? In my opinion (and according to the reactions I've heard), people really don't like to live without their code completion for starters. They feel dynamics is a step back (towards plain old scripting languages aka VBScript, JavaScript, ... just to name a few). So in this, and next, post(s), let's look at dynamic programming, what it is, and how it can help solve some of our more practical issues in programming. Because, let's face it, a language like Ruby does the dynamic thing and is widely popular, there must be some revenue in employing dynamics, no?

First of, let's review a simple example of dynamic (one of the many found out there).

Dynamic can represent any type:
dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();
And I can quite easily assign these variables to their statically typed counterparts:
int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;
So, I hear you think, that's like var and object. Indeed, like var and object, but with a different flavour. Because with var and object I can also do something like this:
object o1 = 7;
object o2 = "a string";
var v1 = 7;
var v2 = "a string";
Looks the same, right? Yes, but not quite. See, the thing is, object and var are still statically typed, meaning that at compile time their type is checked. The compiler knows o1 is of type integer and o2 is of type string, just as it knows for v1 and v2. The d1, d2, d3 and d4 variables, however, are dynamically typed, meaning their type is not checked at compile time, but at run time.

For a dynamic type I can do this:
int oKButCrashAtRunTime = d2;
At compile time I will get no errors whatsoever for this line of code. The compiler says it is valid.

Something I cannot do for object or var:
int notOkAtCompileTime = o2; //compile time error
int alsoNotOkAtCompileTime = v2; //compile time error
At run time however, the line of dynamic code will give me a big fat runtime exception. It's not because something is dynamic you can suddenly assign a string to an integer. So with dynamic types, you need to be extra careful.

These runtime exceptions are part of the reason why people don't like dynamic programming. You only know you've done bad once it crashes (in the user's face). But then why are there tons of programs written in dynamic languages like Ruby? Well, mainly, because Ruby programmers employ a slightly different way of writing code. And if you want the same confidence for your (partly) dynamic .Net code as Ruby programmers have for their (totally) dynamic Ruby code, you will have to learn some of those best practices. Those however, together with a practical .Net example, I will leave for a next post.

Also, dynamic programming brings in new possibilities when developing code. For starters, you get a much easier experience when working with COM objects (eg. in Excel, Word, but also objects from JavaScript). Another pro is the ability to add dynamic behaviour to your static programs. This as well I will leave for one of my next posts.