I have a C# application that stores python script files (*.py) as strings. I load them using:
scriptEngine.CreateScriptSourceFromString(code);
There are several approaches for custom import handling in IronPython and Python in general. Most concepts are defined in PEP 0302 (New Import Hooks).
Two python mechanisms that can solve the requirements are meta_path and path_hooks. Both can be implemented in Python or (in case of IronPython) C#/.NET as well. Given that the question concerns hosting IronPython from C# implementing the import infrastructure can work either way.
Using meta_path
IronPython ships with ResourceMetaPathImporter which allows you to have a ZIP-archive containing your scripts as an embedded resource. Assuming such an archive is called scripts.zip
contained in the currently executing assembly, the required setup could look like:
var engine = Python.CreateEngine();
var sysScope = engine.GetSysModule();
List metaPath = sysScope.GetVariable("meta_path");
var importer = new ResourceMetaPathImporter(Assembly.GetExecutingAssembly(), "scripts.zip");
metaPath.Add(importer);
sysScope.SetVariable("meta_path", metaPath);
This approach works well if the assemblies and scripts are known and ZIP-packaging does not disturb the development process.
Using path_hooks
Path hooks contain a chain of importers that are queried for all items in sys.path
in order to determine if they can handle a given path. An importer similar to zipimport.cs but responsible for embedded resources in DLLs/EXEs instead of ZIP archives.
This could provide a more general approach that handles additional files by just adding a DLL to the path.
Using PlatformAdaptationLayer
A third approach works by providing a PlatformAdaptationLayer which is part of Microsoft.Scripting
/IronPython. This answer shows a full working example of an platform adaption layer resolving embedded resources of a predefined assembly and package namespace.
General note: Related issue/discussion on github.
You could create the different scripts as one function each and call those functions based on arguments given
ScriptScope scope = scriptEngine.CreateScope();
scope.SetVariable("language", "en");
scriptEngine.Execute(scope);
and the python (silly example I know):
def doEnStuff():
print "english"
def doEsStuff():
print "espagna"
if language == "en"
doEnStuff()