.Net Core – Doppelt geladene Assemblies

Wurde mal wieder mit folgender Fehlermeldung begrüßt:

System.InvalidCastException :
[A]DatenMeister.Modules.ZipCodeExample.ZipCodeModel cannot be cast to
[B]DatenMeister.Modules.ZipCodeExample.ZipCodeModel.
Type A originates from
'DatenMeister.Modules.ZipCodeExample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\Projekte\DatenMeister\src\Tests\DatenMeister.Tests\bin\Debug\net5.0\DatenMeister.Modules.ZipCodeExample.dll'.
Type B originates from
'DatenMeister.Modules.ZipCodeExample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\Projekte\DatenMeister\src\Tests\DatenMeister.Tests\bin\Debug\net5.0\DatenMeister.Modules.ZipCodeExample.dll'.

Was ist passiert?
Über ein dynamische Assembly.LoadFrom habe ich über ein Plugin-System die Assembly ZipCodeExample eingeladen. Weiterhin habe ich im Quelltext über eine ProjectReference parallel die Typen in der Assembly genutzt.

.Net Core hat hier ein geändertes Verhalten im Gegensatz zum .Net Framework und erzeugt zwei Instanzen der Assembly. Das heißt, dass die Instanziierungen der Typen in dieser Assembly, je nach Aufrufer unterschiedlich sind, obwohl sie scheinbar vom gleichen Typ sind… Den Unterschied erkennt man über die Eigenschaft m_assembly in dem dahinterliegenden Typ.

Nochmal:
Programm lädt Plugins ein und Plugin-Start-Methode auf
Plugins instanziiert ein Hilfsobject ZipCodeModel und speichert es in einer ObjektDatenbank

Programm ruft eigentliche Routine auf, die das ZipCodeModel per ProjectReference nutzt
Die Objekt-Datenbank gab das per Plugin erzeugte Objekt zurück (da gleicher FullName).
Allerdings passen die Typen nicht zueinander, da das per Plugin erzeugte Objekt vom anderen Typ als die Project Reference ist.

Unschön… hier hatte ich auch mal vor einiger Zeit ein Issue erzeugt über das ich eine sehr schöne Erklärung erhalten hatte: Assembly Loading via ProjectReference and Assembly.LoadFile upon same file leads to two instances · Issue #36787 · dotnet/runtime (github.com)

Die Lösung:
Über folgenden Artikel habe ich die Information erhalten, dass Load statt LoadFrom das doppelte Einladen vermeidet. ==> Plugin Loader is now working correctly by using Load instead of Load … · mbrenn/datenmeister-new@3c87d92 (github.com)

Das Ergebnis:

Success, wo man auch immer hinschaut.