In the previous post I showed how to consume extension methods without modifying either the assembly containing the extension methods or the assembly being extended. The price for this was having to create a third assembly. In this post, I will bring the scenario much close to the desired state.
Before I do that, I will illustrate how I would like IronPython to behave.
First, again we have two assemblies …
WE WANT THIS
And what we would like to do is simply consume the extension methods - something like this
As I demonstrated in my last post, it’s not that simple.
WE CAN GET VERY CLOSE TO THE DESIRED BEHAVIOR
A little bit of C# and some CodeDOM magic and we can do this…
A CLOSER LOOK AT import_extension_methods()
- The source is attached
- The Isotope.IronPythonUtil is an assembly that contains a method CreateIronPythonExtensionMethodAssembly()
- loads an assembly from a DLL
- loads all the assemblies to which that first assembly refers
- finds all the extension methods in the first assembly
- builds a CodeDOM of all the ExtensionType attributes
- builds a placeholder class (see previous post about the need for this)
- and generates a DLL
- The original code generated a “C#” file and used CodeDOM to compile it to an DLL. This one generates a CodeDOM manually so it is faster to create the Dll.
- The source code is included as an attachment
- The situation is much improved now
- There’s a little bit of delay in generating and loading this third assembly, but it’s nothing unreasonable relative to the general speed of IronPython import speed
- we should just be able to keep that 3rd dynamically created assembly in memory and not persist it to disk – QED
- Ultimately I hope this support arrives “out-of-the-box” with IronPython. It’s just part of supporting the “batteries included” principle.