views:

787

answers:

2

First Some Background (incase it helps):

My application is a Web-based framework recently upgraded to v3.5 of the .Net Framework but does not use a Master Pages / User Controls system. It's more akin to the MVC pattern (although much older) and outputs pure HTML down the response stream from Templates. The Python expressions allow some rules and template variations to be achieved.

The old way

When embedding the IronPython 1.x engine in C#, we were able to do code such as:

PythonEngine pe = new PythonEngine();
Assembly a = Assembly.LoadFile("path to assembly");
pe.LoadAssembly(a);
pe.Import("Script");

there is no Import() method in ipy 2.0 and the ImportModule() method doesn't seem to work the same way. The Import() alleviated the need to put a line in every python script we write, such as:

from MyAssembly import MyClass

the fact that MyClass is full of static methods, means that calls to MyClass.MyMethod() work really well. I can't just instansiate an object and assign it to a variable in scope as the assembly that MyClass is contained in is dynamically loaded at runtime.

Now to the issue

I have sorted out all the other parts of the integration of IronPython 2.0 but would prefer not to require my implementers to type "from MyAssembly import MyClass" at the top of every script they write (just seems silly when it was not necessary in ipy 1.x) and likely to be a support issue for a while too.

And finally the question

Has anyone had this issue and resolved it? Am I doing things the wrong way for the DLR? or am I missing something obvious?

I'm not sure of the detail required for someone to help, but I hope this is enough.

+5  A: 

Once the assembly's loaded, you can execute the import in the Scope you're using to run the script:

ScriptEngine engine = Python.CreateEngine();
engine.Runtime.LoadAssembly(a);
string code = "from MyAssembly import MyClass";
ScriptSource source = engine.CreateScriptSourceFromString(code, "<import>", SourceCodeKind.Statements);
CompiledCode c = source.Compile();

Scope scope = engine.CreateScope();
c.Execute(scope);

// then run your script in the same scope

We do something similar in our product.

(Hopefully this is valid C# - I actually tried it in IronPython itself, because it was more convenient.)

wilberforce
+1  A: 

Thanks Wilberforce,

In the end I did the following:

Assembly a = Assembly.LoadFile("path to assembly");
object var = a.CreateInstance("MyNamespace.MyClass");

Scope.SetVariable("MyClass", var);

This made an object of my class in C# and then passed it to the IronPython scope as a variable.

Note, that this is creating the object in the C# scope (AppDomain) and just passing it to the IronPython. This seems (so far) to work for my problem because the object I am passing is full of only static methods but may not work for a class with state.

kolosan