powershell 2 new-object "Cannot find type..." exception when instantiate .net class implemented interface from external library
Asked Answered
K

2

5

I have found an issue that is quite easy to reproduce. Please advise if there is any work around for this?

There are two .Net libraries libraryA.dll and libraryB.dll. And each library has one interface InterfaceA and InterfaceB. ClassAA implements InterfaceA and lives in libraryA. ClassAB implements InterfaceB and lives in the same libraryA. The same way ClassBB - LibraryB - InterfaceB; ClassBA - LibraryB - InterfaceA

New-Object works correctly when ClassAA and ClassBB are instantiated but not ClassAB or ClassBA. They constantly fail to instantiate.

Here you are powershell code

[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)

Many Thanks,

Andrey

Keloid answered 17/11, 2010 at 10:30 Comment(0)
S
6

Instead of ::LoadFile, use:

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

When you use ::LoadFrom the assembly will be loaded into a context with the directory it was loaded from, referenced assemblies in that same directory will automatically be resolved. ::LoadFile is meant for loading assemblies that share an identity but are in different directories and does not keep any load context, so referenced assemblies are not resolved.

Selfsealing answered 2/1, 2013 at 21:0 Comment(2)
When I do it this way I still get the error: New-Object : Cannot find type [[MyNamespace]::Class1]: verify that the assembly containing this type is loaded.Mcroberts
Same here, I need to load this on an Ubuntu runner in Github Actions. The log outputs even shows that the loading was succesful. But when I try to instantiate a class, I get the same error: Cannot find type [Namespace.Classname]: verify that the assembly containing this type is loadedNovelize
J
3

The answer to this question solves your issue: How can I get PowerShell Added-Types to use Added Types

The key is to use the AppDomain.CurrentDomain.AssemblyResolve event.

You can, for example, add the AssemblyResolver class (from the post above) to your LibraryA and then use [Utils.AssemblyResolver]::AddAssemblyLocation("LibraryB.dll") to pull in the LibraryB reference when needed.

Or, just to prove the point:

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

Note that you have a circular dependency in your example above: LibraryA is referencing LibraryB and LibraryB references LibraryA. You will probably want to fix that first - assuming you have the same in your real project...

Jolandajolanta answered 20/5, 2011 at 20:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.