Geeks With Blogs

News Locations of visitors to this page
Brian Genisio's House of Bilz

Shout it kick it on DotNetKicks.com

DynamicWrapper project on CodePlex

Edit: DynamicWrapper does not work in SIlverlight as I first though.  My unit tests passed, but in runtime I get an exception when I try to use the class.  I will be looking at some alternatives.

Over the past few weeks, I have been working on a utility that I have wanted for years: something that allows me to apply an interface to an object that matches the contract but doesn’t actually implement the interface.  In other words, I’ve wanted duck typing in C#.  The code and project can be found on CodePlex.  It is set up so you simply copy one file into your solution and use the extension methods.

Why did I want this?  Because I write a lot of unit tests and I develop in .Net with C#.  Because I write way too many wrapper classes to make my code testable.  For example, lets say that I have a class that I want to test and it acts upon a framework object:

public sealed class FrameworkClass
{
    internal FrameworkClass() {}
    
    public int X {get; set;}
    public int Y {get; set;}
    public int Calculate() { return DoSomeStuff(); }
}
public class MyClass
{
    public void DoSomethingWithFrameworkData(FrameworkClass value)
    {
        // Do Something
    }
}

The problem is that I can’t test MyClass because it is dependent upon FrameworkClass which I can never construct myself (it is sealed with an internal constructor and no interface).  The solution for this is simple but tedious – create a wrapper class that implements an interface and proxy through the wrapper class to the real object.  This approach works, but I can say this: I am sick of writing wrapper classes!

This is why I created this DynamicWrapper utility.  It exposes two extension methods: realObject.As<Interface>() and wrapper.AsReal<ConcreteClass>().  It uses Reflection to emit a dynamically generated wrapper class that implements the interface, and wraps your object for you.  It sounds complicated, but it is extremely simple to use.

Here is an example. Start by creating an interface that looks like the FrameworkClass:

public interface ICalculatable
{
    int X {get; set;}
    int Y {get; set;}
    int Calculate();
}

Modify your class to depend on ICalculatable:

public void DoSomethingWIthFrameworkData(ICalculatable value) {}

Now, when you pass the framework class into the MyClass, you can wrap it with the interface:

myObject.DoSomethingWithFrameworkData(frameworkObject.As<ICalculatable>());

If you need the framework object to pass back to the framework, it is really simple:

wrapper.AsReal<FrameworkClass>()

That’s all there is to it!  The utility is very simple.  It just gets me out of the business of writing (and maintaining) wrapper classes. I am now free to get back to real development.

*On a slightly related note, I will be focusing my learning efforts towards Ruby in the coming months.*

Posted on Friday, September 18, 2009 4:44 PM | Back to top


Comments on this post: Introducing DynamicWrapper

# re: Introducing DynamicWrapper
Requesting Gravatar...
Cool little piece of program. One question. Does the wrapper dictionary need to be thread safe?
Left by Mike Ward on Sep 19, 2009 12:41 AM

# re: Introducing DynamicWrapper
Requesting Gravatar...
@Mike: Good point. I think the most important thing is that wrapperBuilder.CreateType() never gets called twice for the same wrapper. It will fail.

It seems to me that some locking is in order to make sure this never happens. Probably some better error handling would be prudent as well.
Left by Brian Genisio on Sep 19, 2009 2:05 AM

# re: Introducing DynamicWrapper
Requesting Gravatar...
I wasn't concerned about double entries. I was thinking that there might be a conflict when accessing the dictionary for one type while adding a new one. Might raise a sequence modified while enumerating exception. Not sure how dictionaries work under those circumstances.

The more I look at this code the more excited I am about using it. Took me a few minutes to grok it but now I'm getting it.
Left by Mike Ward on Sep 19, 2009 2:58 AM

# re: Introducing DynamicWrapper
Requesting Gravatar...
Hey, Brian - nice job from first looks; I think I like the extension method approach. My favorite line is:
if (realObject is T) return realObject as T;
I am pretty sure I would not have thought of that one! :-)

On that other subject: I have not looked at the code long enough to understand the issue above, but I believe the WrapperDictionary class should be made thread-safe (as you all have noted). A side-effect of implementing as extension methods, I would think, since you then need the static dictionary. It is possible that an implementation without extension methods might be better? I like the extension method usage syntax, however, very much.
Left by Bill on Sep 20, 2009 12:31 AM

# re: Introducing DynamicWrapper
Requesting Gravatar...
This is nice. I actually created something more or less functionally equivalent to this for use on my last project, only I used Castle.DynamicProxy2 to do the heavy lifting. I considered going the DynamicAssembly route but thought it would be too involved. From the looks of your implementation it would seem I was wrong :)
Left by Casey Kramer on Sep 21, 2009 2:12 AM

# re: Introducing DynamicWrapper
Requesting Gravatar...
What is the difference between this and a mocking framework like Rhino.Mocks?
Left by Travis on Sep 21, 2009 4:56 AM

# re: Introducing DynamicWrapper
Requesting Gravatar...
@Travis: DynamicWrapper facilitates the use of mocking frameworks such as RhinoMocks. You see, before DynamicWrapper, I would do the exact same thing -- generate an ICalculatable interface and have MyClass rely on it. This lets me mock ICalculatable with a mocking framework.

In order to get this, I would need to write a wrapper class:

public class FrameworkClassWrapper : ICalculatable
{
private readonly FrameworkClass _frameworkObject;
public FrameworkClassWrapper(FrameworkClass frameworkObject)
{
_frameworkObject = frameworkObject;
}

int X
{
get { return _frameworkObject.X; }
set { _frameworkObject.X = value}
}

int Y
{
get { return _frameworkObject.Y; }
set { _frameworkObject.Y = value}
}

int Calculate() { return _frameworkObject.Calculate(); }

Then, when you call into MyClass in production code, you would do it this way:

myObject.DoSomethingWithFrameworkData(new FrameworkClassWrapper(frameworkObject);

That wrapper class is really tedious, and needs to be updated every time ICalculatable changes. DynamicWrapper will generate FrameworkClassWrapper for you at runtime so you can be on your way to mocking out the framework object using RhinoMocks, Moq, etc much quicker.
Left by Brian Genisio on Sep 21, 2009 9:44 AM

# re: Introducing DynamicWrapper
Requesting Gravatar...
You might want to check out this project:

http://www.deftflux.net/blog/page/Duck-Typing-Project.aspx
Left by Jordan on Sep 21, 2009 11:24 AM

# re: Introducing DynamicWrapper
Requesting Gravatar...
@Jordan: Thanks for that. It turns out that there are several approaches to this problem, including the "Duck Typing Project" and "Castle DynamicProxy".

Quite honestly, my approach in DynamicWrapper is to do one thing -- dynamically create wrapper classes. I was looking for something that doesn't require linking against an external DLL (copy the file into a project) so that I can use my work in my job at a big, big, company.

The goal here really isn't duck typing, per se, but to let me write testable code without writing wrappers.

Thanks for the link, for people who might want more than what DynamicWrapper provides.
Left by Brian Genisio on Sep 21, 2009 1:11 PM

Your comment:
 (will show your gravatar)


Copyright © Brian Genisio's House Of Bilz | Powered by: GeeksWithBlogs.net