Welcome to

Magenic Technologies Community Blog

Sign in | Join | Help

Aaron's Technology Musings

Who let this guy on the podium?

DuckCallLib v0.2, Introducing object.As<T>

Scratching another itch, and after reading some feedback from mihailik on my previous post - I decided to implement some additional functionality in DuckCallLib to make it more useful.  As before, the bits are available on codeplex.

So, again, with great fanfare, I introduce my first cut at an dynamic proxy mechanism that works generally for objects that leverages the duck typing mechanism we previously built.  The purpose of this is to allow a consumer of an object to recognize when an object they don't control has certain behavior, and without having to implement a wrapper on your own, simply apply an interface to the object at runtime, whether it explicitly supports the interface or not.

Usage is generally as follows:

interface IEggable { string LayEgg(); }
class Platypus { public string LayEgg { return "egg"; } } //notice it does not implement IEggable

//we don't know for sure if a platypus can lay eggs, since we are dealing with it as an object, but we can try
object someObjectThatMightLayEggs = new Platypus();
var eggLayingPlatypus = someObjectThatMightLayEggs.As<IEggable>();
Assert.IsTrue(eggLayingPlatypus.LayEgg() == "egg");

Still a work in progress.  I doubt I handle generics well, and I need to something other than crash on method missing, but the hardest part (for me) - generating the dynamic proxy that implements the interface dynamically using Reflection.Emit (ugh) is done.

Enjoy, and as always, feedback is appreciated.

Update, duh moment, I just realized I started to re-implement this (Jason Bock) and this (Castle Project).  Ah well, if nothing else, going through creating one of these has given me a much better sense for how to do nifty stuff with Reflection.Emit. 

Published Tuesday, July 01, 2008 4:31 PM by aarone

Filed under:

Comments

# re: DuckCallLib v0.2, Introducing object.As<T> @ Tuesday, July 01, 2008 5:17 PM

Great work, Aaron. And thanks for mentioning me in credits :-)

Your code already handles properties and events, since from CLR point of view they are mere methods anyway (get/set, add/remove).

What your code doesn not handle, is output parameters and generic methods. Also your method signature matching is a bit naive (name+parameter count).

Also you would probably want to reuse emitted stuff, since it won't be purged and stays in AppDomain forever anyway. One wouldn't expect every call to a certain method to create a new assembly.

Also, at some point it might be sensible to fire PEVerify to check generated assembly. Reflection.Emit makes almost no checks on emitted code. If the emission goes bad, CLR makes every effort to entertain you with a sudden enigmatic error message.

mihailik

# re: DuckCallLib v0.2, Introducing object.As<T> @ Tuesday, July 01, 2008 5:27 PM

Thanks mihalik,

I can assure you that I learned the hard way about what happens when you Reflection.Emit lets you emit stuff that .NET doesn't like - 80% of the time working on this was spent:

a.) Learning IL (haven't written assembler or anything like it in 12 years... talk about memory lane!)

b.) Discovering my Emit calls were not working, and writing classes and looking at them in reflector to see what the IL should look like

c.) Thankfully, gaining a healthy appreciation for how this stuff works

The good thing is that after that experience, writing a better method matcher should be cake :)

I know the current implementation is naive, it was more getting POC done now and then building on it.

Of course, as I wrote in the post, it looks like a lot of folks have gone down this road.  I may decide to just write something that takes advantage of stuff already done, but adds the semantics I like.

aarone

# re: DuckCallLib v0.2, Introducing object.As<T> @ Friday, July 18, 2008 10:00 AM

Have you considered used the new Expression stuff in .NET 3.5 instead of the Reflection.Emit API? It has the same power as but is much more mantainable.

Gustavo Guerra

# re: DuckCallLib v0.2, Introducing object.As<T> @ Friday, July 18, 2008 10:05 AM

Believe me - I tried to use the Expression stuff.   Heck, I wrote a library (MetaLinq) for making that kind of thing easier to do.

There is no capability (at least that I am aware of) in the expression builder to create brand new types from scratch and start adding methods.  I would love someone to show me where you can do something like that though, because Reflection.Emit is definitely a painful experience at first given that it is often like programming into a black hold and hoping you see the desired result come out the other end.

aarone

New Comments to this post are disabled
Powered by Community Server, by Telligent Systems