views:

939

answers:

3

I'm currently researching the 2nd edition of C# in Depth, and trying to implement "dynamic protocol buffers" - i.e. a level of dynamic support on top of my existing protocol buffer library. As such, I have a DlrMessage type derived from DynamicObject. After a little bit of playing around I've managed to get it to respond to simple properties with remarkably little code, but I want to go a lot further - and to really understand what's going on.

So far I haven't found any good explanations of the DLR - and a lot of the blog posts are effectively out of date now, as things have changed (I believe) between the previous CTP and .NET 4.0 beta 1. The MSDN documentation for DynamicObject is pretty minimal at the moment.

My most immediate query is whether there's a simple way of saying, "Use reflection to bind any calls I can't handle, using this particular object." (In other words, I want to augment the existing reflection binding rather than doing everything myself, if possible.) Unfortunately I'm not getting very far by guesswork.

Are there any definitive and recent sources of documentation I should know about? I'm aware that part of writing about a new technology is exploration, but a helping hand would be appreciated :)

+11  A: 

Best source I've found and read frequently is the last years worth of Chris Burrow's posts on his blog.

There's also the official DLR documentation page which is off the main DLR site.

TheSoftwareJedi
Ooh, that looks very handy, thanks - I particularly like the fact that it's all recent :) The "library author's introduction" looks like it's *exactly* the right thing.
Jon Skeet
Well that WAS your question. "...recent sources of documentation..." :) Is there a badge for having an answer accepted by Jon Skeet?
TheSoftwareJedi
+2  A: 

I too am researching this at the moment and there is not too much info yet. I cant help with your query but below is some information I have found:

There is a fair amount within the PDC videos.

http://channel9.msdn.com/pdc2008/TL44/

http://channel9.msdn.com/pdc2008/TL10/

This article talks about how the DLR works with IronPython: http://msdn.microsoft.com/en-us/magazine/cc163344.aspx

There is a very small amount in the training kit preview at: http://www.microsoft.com/downloads/details.aspx?FamilyID=752cb725-969b-4732-a383-ed5740f02e93&displayLang=en

Hope this helps

Alex

alexmac
+1  A: 

By default DynamicObject will say "fallback to reflection" if your Try* functions return false. So you already can inherit and add properties/fields/methods to your subclass that will all be handled by reflection if the dynamic path doesn't do the lookup.

Going more in depth you might want to look at IDynamicMetaObjectProvider. At this lower level the way you say fallback to reflection is to call the Fallback* method on the incoming DynamicMetaObjetBinder. This then lets the calling language to provide the resolution. You can then return that AST or compose it into a larger AST whcih you return. Basically Fallback* let you get the AST that the calling language would produce including the correct error (exception, undefined in JS, etc...).

The way DynamicObject does the fallback to reflection is that it actually calls the binder's Fallback* method twice. The first time it falls back without an "errorSuggestion" parameter. This gets either the error or the AST which was built using reflection. It then produces an AST which is something like:

if(TryGetMember("name", out value)) {
   return value;
} else {
   return resultOffallback;
}

It then takes this combined AST and actually hands it in as the error suggestion for the binder on a 2nd fallback. The binder should then respect this errorSuggestion if the binding is unsuccessful. But if the .NET member is present then errorSuggestion is thrown away and the .NET binding takes precedence. And finally if the language doesn't know if the binding was successful (e.g. the language has a "method missing" type feature) it can again combine the ASTs w/ it's dynamic checks. So using Fallback you can not only say do reflection but also you can choose whether dynamic or static members take precedence.

Dino Viehland
Thanks. The problem with DynamicObject is that it falls back to reflection on *this* object - I'd like it to fall back to reflection on a *different* object, and I suspect for that to work I would have to implement IDynamicMetaObjectProvider, which is more trouble than it's worth in this case. I've ended up copying a load of methods into my dynamic type which just proxy on to the other object, so I still get the benefit of reflection. Ugly, but it works.
Jon Skeet
@Jon Skeet You write a simple T4 file to codegen this adapter pattern for any object quite easily within a partial class. If you ask such a question, I'll post a solution for you!
TheSoftwareJedi