当实例化.net类从外部库实现接口时,powershell 2 new-object“找不到类型...”异常

时间:2010-11-17 10:30:45

标签: exception .net-3.5 powershell powershell-v2.0

我发现了一个很容易重现的问题。请告知是否有任何解决方法?

有两个.Net库libraryA.dll和libraryB.dll。每个库都有一个接口InterfaceA和InterfaceB。 ClassAA实现了InterfaceA并且存在于libraryA中。 ClassAB实现了InterfaceB并且位于同一个库A中。同样的方式ClassBB - LibraryB - InterfaceB; ClassBA - LibraryB - InterfaceA

当实例化ClassAA和ClassBB而不是ClassAB或ClassBA时,New-Object可以正常工作。他们经常无法实例化。

这里是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)

非常感谢,

安德烈

2 个答案:

答案 0 :(得分:6)

使用:

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

当您使用::LoadFrom时,程序集将被加载到其加载目录的上下文中,同一目录中的引用程序集将自动解析。 ::LoadFile用于加载共享标识但位于不同目录中的程序集,并且不保留任何加载上下文,因此不会解析引用的程序集。

答案 1 :(得分:3)

这个问题的答案解决了您的问题: How can I get PowerShell Added-Types to use Added Types

关键是使用AppDomain.CurrentDomain.AssemblyResolve事件。

例如,您可以将AssemblyResolver类(从上面的帖子中)添加到LibraryA,然后在需要时使用[Utils.AssemblyResolver] :: AddAssemblyLocation(“LibraryB.dll”)来引入LibraryB引用。 / p>

或者,只是为了证明这一点:

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

请注意,上面的示例中有一个循环依赖项:LibraryA引用LibraryB,LibraryB引用LibraryA。您可能希望先修复它 - 假设您在实际项目中具有相同的内容......