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

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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.
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 loaded
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...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.