Welcome to MSDN Blogs Sign in | Join | Help

IronPython: Consuming Extension Methods in IronPython Part II

This is an update from my original post: http://blogs.msdn.com/saveenr/archive/2008/11/14/consuming-extension-methods-in-ironpython.aspx

Before proceeding, please read the original article. It will help in understanding this one.

 

A QUICK RECAP FROM THE ORIGINAL POST

We have two assemblies. One assembly (the extender) contains extension methods that are assigned to a class in the other assembly (the extended).

 

image

And here is the corresponding source code

image

At this point both C# and F# can consume the extension methods defined in ClassLibB.

IronPython can’t.

image

 

IronPython requires us to add the “ExtensionType” attribute.

Our first attempt is this.

image

And the source code looks like this …

image

And now IronPython can consume the extension methods.

image

 

THE PROBLEM AND THE FIX

As you can see, I had to modify the source code of Assembly B. In a lot of real-world situations it’s not possible to modify Assembly A or B.

Here are some reasons why:

  • You may not have the source code for assembly
  • You have the source code, but modification is useless because the original assembly was signed by the author
  • You have the source code, but you do not have the legal rights to modify or distribute the source

It this point, we’re stuck – but here’s the great news. Those ExtensionType attributes don’t have to be in either Assembly A or Assembly B. You can create a special Assembly C that has the sole purpose of storing these attributes. If you load Assembly C then IronPython can see the extension methods and it doesn’t require any changes to Assembly A or Assembly B.

 

IMPLEMENTING THE SOLUTION

 

image

And the source code looks like this:

image

 

VERIFYING THAT IT WORKS

 

Add a reference to AssemblyC and then import it. Then the extension methods will be visible to IronPython

image

 

PARTING THOUGHTS

 

  • There’s still the pain of generating Assembly C – a future post will simplify this task
  • Notice that Assembly C contains a tiny class “ClassLibC.ClassC”. In order for this all to work it seems that AssemblyC needs to contain at least one public class. (If you leave this palceholder class out, then you will be able to add a reference to Assembly C but the import will fail)
  • Many thanks to Harry Pierson for letting me know that the ExtensionType attribute can be in any assembly.
  • The source code is attached if you want to try this for yourself
Published Thursday, February 05, 2009 8:43 PM by saveenr

Attachment(s): DemoFindExtensionMethods.zip

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: IronPython: Consuming Extension Methods in IronPython Part II

Nice workaround, but we shouldn't *have* to go through such hoops as creating an assembly ahead-of-time.  IP should be using the attributes that already work quite well for other languages, without resorting to custom duplication.

It's entirely possible this is technically impossible, but I don't see why that would be.

Friday, February 06, 2009 12:47 PM by kfarmer

# re: IronPython: Consuming Extension Methods in IronPython Part II

I agree.

The reason IronPython doesn't automatically load the extension methods is not (from what I understand) an issue of technical possibility but rather performance. When importing assemblies, were it to check for extension methods on each import then all imports would slow down a bit.

On the other hand, It would still be useful to have a way to express something like "from AssemblyB import __extension_methods__"  This approach wouldn't hurt import performance in the general case and it would make it far simpler to consume the extension methods..

In my next couple of posts I should be able to demonstrate that we can add this feature ourselves.

Friday, February 06, 2009 1:18 PM by saveenr

# re: IronPython: Consuming Extension Methods in IronPython Part II

That is precisely the mechanism I was hoping to have.  Actually, back when they were first demonstrated during PDC05, I was hoping C# would allow finer scoping of extension method loading.  Something akin to a (Pythonic) "using <namespace/extension class> extend <type>".

Saturday, February 07, 2009 2:58 AM by kfarmer

# re: IronPython: Consuming Extension Methods in IronPython Part II

Which version did you test against? I checked with IronPython 2.0 and you don't need to have an empty public class in the "enabler" assembly. Moreover, the extension methods seem to be picked up as soon as the (enabler) assembly is loaded into the AppDomain. See the doc summary for DomainManager_AssemblyLoaded of PythonBinder:

http://www.google.com/codesearch/p?hl=en#DoYEm5hLxg0/Merlin/Main/Languages/IronPython/IronPython/Runtime/Binding/PythonBinder.cs&q=pythonbinder&l=763

It reads, "Currently DLR-style extension methods become immediately available w/o an explicit import step."

Tuesday, February 17, 2009 5:13 PM by Atif Aziz

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker