views:

26

answers:

2

I have an IronPython 2.6/2.7 script I am writing which imports a lot of assemblies.

In other words, at the top of the script it does this...

clr.AddReference( "System.Xml" )
import System.Xml

Except it doesn't do this for 1 assembly, but for 10 assemblies.

Some of the modules are built-in .NET assembllies and some are assemblies I have made.

I'd like to simplify my script so that it loads one assembly that I will build. I want to then call a method in that assembly that will do the "AddReference" and "import" for the 10 assemblies. The primary goal of all this is to minimize the length/complexity of the script.

So in the end I would see it working like this

clr.AddReferenceToFileAndPath( "d:\\myassembly" )
import MyAssembly
MyAssembly.ImportAllAssembliesIReallyWant()

My core problemis despite reading all the information I could find on ScriptRuntime, ScriptEngine, scopes, etc. - I still can't figure out how to write a method in "MyAssembly" that affects what modules are loaded in the calling script.

A: 

I think that the only way to do this is going to be to access the ScriptEngine from within your ImportAllAssemblies() method and execute the commands that would normally be executed. You should be able to dynamically generate the statements based on what assemblies you want to load and that are referenced etc.

Hope that helps point you in the right direction.

Matthew Steeples
+2  A: 

One way to go about this would be to create a built-in module which does this. You can do this with:

[assembly: PythonModule("mymodule", typeof(MyModuleType)]

public static class MyModuleType { [SpecialName] public static void PerformModuleReload(PythonContext context, PythonDictionary dict) { context.DomainManager.LoadAssembly(typeof(TypeInAssemblyToLoad)); } }

Just add appropriate LoadAssembly calls for all of the assemblies you care about. The assembly could also populate members in dict that you want available.

Another (and possibly simpler) way would be to simply have a .py file which does all of the clr.AddReference calls you need and have every module import that one file. The import mechanism will do the appropriate caching so it will only load once but will ensure all of the assemblies are available for each module which needs them.

Dino Viehland
Dino, I've decided to try the first method you wrote about: creating a module. So far this solves half my problem. So, following this technique in the initialization of my module it takes care of the doing the equivalent of "clr.AddReferenceToFileAndPath" but the remaining part I still need to cover: doing the equivalent of "import MyAssembly". How can I achieve the doing the "import" in the Module?
namenlos
What you can do is something like:
Dino Viehland
A rough way of doing this would be to get the exported types from the assembly (there's a method on assembly objects to do that) and then call DynamicHelpers.GetPythonTypeFromType for each type and stick the result into the dictionary which PerformModuleReload gives you. Then your user can do from mymodule import * and they'll get everything that's in the assembly.
Dino Viehland