2010-11-17 49 views
3

J'ai trouvé un problème assez facile à reproduire. S'il vous plaît aviser s'il y a du travail pour cela?powershell 2 new-object Exception "Ne peut pas trouver de type ..." lors de l'instanciation de l'interface .net de la bibliothèque externe

Il existe deux bibliothèques .Net libraryA.dll et libraryB.dll. Et chaque bibliothèque a une interface InterfaceA et InterfaceB. ClassAA implémente InterfaceA et vit dans libraryA. ClassAB implémente InterfaceB et vit dans la même bibliothèqueA. De la même manière ClassBB - LibraryB - InterfaceB; ClassBA - LibraryB - InterfaceA

New-Object fonctionne correctement lorsque ClassAA et ClassBB sont instanciés mais pas ClassAB ou ClassBA. Ils échouent constamment à instancier.

Ici vous êtes le code powershell

[System.Reflection.Assembly]::LoadFile(‘c:\LibraryA.dll’) 
[System.Reflection.Assembly]::LoadFile(‘c:\LibraryB.dll’) 

$obj1 = new-object -typeName ClassAA (IT WORKS) 
$obj2 = new-object -typeName ClassBB (IT WORKS) 
$obj3 = new-object -typeName ClassAB (EXCEPTION THROWN) 
$obj4 = new-object -typeName ClassBA (EXCEPTION THROWN) 

Merci beaucoup,

Andrey

Répondre

5

Au lieu de ::LoadFile, utilisez:

[System.Reflection.Assembly]::LoadFrom(‘c:\LibraryA.dll’) 
[System.Reflection.Assembly]::LoadFrom(‘c:\LibraryB.dll’) 

Lorsque vous utilisez ::LoadFrom l'ensemble sera chargé dans un contexte avec le répertoire à partir duquel il a été chargé, les assemblages référencés dans ce même répertoire seront automatiquement résolus. ::LoadFile est destiné au chargement d'assemblages partageant une identité, mais se trouvant dans des répertoires différents et ne conservant aucun contexte de chargement, les assemblages référencés ne sont donc pas résolus.

+0

Lorsque je le fais de cette façon, je reçois toujours l'erreur: New-Object: Impossible de trouver le type [[MyNamespace] :: Class1]: vérifiez que l'assembly contenant ce type est chargé. – James

3

La réponse à cette question permet de résoudre votre problème: How can I get PowerShell Added-Types to use Added Types

La clé est d'utiliser le AppDomain Evénement .CurrentDomain.AssemblyResolve.

Vous pouvez, par exemple, ajouter la classe AssemblyResolver (à partir de la publication ci-dessus) à LibraryA, puis utiliser [Utils.AssemblyResolver] :: AddAssemblyLocation ("LibraryB.dll") pour extraire la référence LibraryB en cas de besoin.

Ou, juste pour prouver le point:

[System.AppDomain]::CurrentDomain.add_assemblyResolve({ 
    If ($args[1].Name.StartsWith("LibraryB")) 
    { 
     Return [System.Reflection.Assembly]::LoadFile("C:\LibraryB.dll") 
    } 
    Else 
    { 
     Return $Null 
    } 
}) 

Notez que vous avez une dépendance circulaire dans votre exemple ci-dessus: Bibliothèque_A fait référence à des références Bibliothèque_B et Bibliothèque_B Bibliothèque_A. Vous voudrez probablement de fixer ce premier - en supposant que vous avez la même chose dans votre projet immobilier ...