2010-10-06 26 views
1

J'ai un script IronPython 2.6/2.7 que j'écris et qui importe beaucoup d'assemblages.Importer des assemblages dans IronPython à partir d'un autre assemblage

En d'autres termes, en haut du script, il le fait ...

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

Sauf qu'il ne le fait pas pour 1 assemblage, mais pour 10 ensembles.

Certains des modules sont des assemblys .NET intégrés et certains sont des assemblages que j'ai réalisés.

Je voudrais simplifier mon script pour qu'il charge un assemblage que je vais construire. Je veux ensuite appeler une méthode dans cet assembly qui fera les "AddReference" et "importer" pour les 10 assemblages. Le but principal de tout ceci est de minimiser la longueur/complexité du script.

Donc à la fin je voyais fonctionner comme cette

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

Mes problemis de base malgré la lecture de toutes les informations que je pouvais trouver sur ScriptRuntime, ScriptEngine, champs, etc. - je ne peux toujours pas comprendre comment écrire une méthode dans "MyAssembly" qui affecte quels modules sont chargés dans le script appelant.

Répondre

0

Je pense que la seule façon de faire cela sera d'accéder à ScriptEngine à partir de votre méthode ImportAllAssemblies() et d'exécuter les commandes qui seraient normalement exécutées. Vous devriez être capable de générer dynamiquement les instructions en fonction des assemblages que vous voulez charger et qui sont référencés, etc.

Espérons que cela vous aide dans la bonne direction.

2

Une façon d'y parvenir serait de créer un module intégré qui fait cela. Vous pouvez le faire avec:

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

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

il suffit d'ajouter les appels LoadAssembly appropriés pour tous les ensembles qui vous passionnent. L'assemblage pourrait également peupler les membres en dict que vous voulez disponible.

Un autre moyen (et peut-être plus simple) consisterait simplement à avoir un fichier .py qui effectue tous les appels clr.AddReference dont vous avez besoin et à ce que chaque module importe ce fichier. Le mécanisme d'importation effectuera la mise en cache appropriée de sorte qu'il ne se chargera qu'une seule fois mais s'assurera que tous les assemblages sont disponibles pour chaque module qui en a besoin.

+0

Dino, j'ai décidé d'essayer la première méthode que vous avez écrite: créer un module. Jusqu'à présent, cela résout la moitié de mon problème. Donc, suivant cette technique dans l'initialisation de mon module, il prend soin de faire l'équivalent de "clr.AddReferenceToFileAndPath" mais la partie restante que je dois encore couvrir: faire l'équivalent de "import MyAssembly". Comment puis-je réaliser l'importation dans le module? – namenlos

+0

Ce que vous pouvez faire est quelque chose comme: –

+0

Une manière grossière de faire ceci serait d'obtenir les types exportés de l'assemblée (il y a une méthode sur les objets d'assemblage pour faire cela) puis appelez DynamicHelpers.GetPythonTypeFromType pour chaque type et collez le résultat dans le dictionnaire que PerformModuleReload vous donne. Ensuite, votre utilisateur peut faire à partir de mymodule import * et il obtiendra tout ce qui est dans l'assemblage. –