Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[.NET] Assembly.LoadFrom en IPlugin cast = exception

Pagina: 1
Acties:

  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 16:53
Ik heb een plugin host geschreven met 3 projecten in 1 solution

1) PlugInSDK, met een IPlugIn interface
2) PlugIns, met de implementatie van de in 1) gedefinieerde interface
3) Start app, waarin ik dynamisch een assembly laad en zoek naar een IPlugIn class en deze instantieer via Activator.CreateInstance

Alle 3 projecten heb ik gesigned met een key.

Probleem: als ik run dan krijg ik een cast exception maar alleen indien ik gesigned heb; quote ik de attribuut-signing uit, dan gaat het wel goed.

Ik heb er iets over gelezen dat een cast volledig op assembly qualified name gaat; dit houdt in dat je niet meerdere IPlugIn interface definities in verschillende projecten mag hebben. Dit heb ik ook niet. Het enigste verschil tussen wel en niet een exception is het feit dat ik sign.

Hoe zit dit nou ?

  • whoami
  • Registratie: December 2000
  • Laatst online: 29-11 22:54
Heb je die gesignde assembly in de GAC geinstalleerd?
Toon eens de code mbt Activator.CreateInstance. Ik geloof dat je daar ook het versie-nr enzo zult moeten mee opgeven.

https://fgheysels.github.io/


  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Wat je wil moet mogelijk zijn. Iets dergelijks heb ik een jaar geleden ooit gebruikt. Ik heb wel gemerkt dat er d.m.v. signing wat extra complicaties zijn, waarbij degene die het eerste in me op komt build-nummers zijn in je assembly. Het build-nummer wordt meegenomen in je strong name.

Maar ik denk niet dat dat met jouw iets te maken heeft, omdat als het goed is alle projecten tegelijk gecompileerd worden en elke assembly slechts éénmaal gemaakt wordt. Dan heb je het probleem met buildnummers en strong names niet denk ik.

Een mogelijk ander probleem is dat je wellicht de definitie van IPlugin in meerdere assemblies hebt zitten. Meerdere implementaties van een interface mag wel, maar meerdere definities mag niet want dan is je volledige naam(waar o.a. de assembly naam in zit) anders.

Volgens mij is je opzet wel goed:
PlugInSdk: bevat definitie IPlugin.
Start app: static reference met PlugInSdk. imports IPlugin maar definieerd niet overnieuw (bevat de IPlugin sourcefile niet). Laad dynamisch de PlugIns assembly.
PlugIns: static reference met PlugInSdk. imports IPlugin maar defnieerd niet ovvernieuw (bevat de IPlugin sourcefile niet). Bevat een klasse die IPlugin implementeerd.

Een tip is het gebruiken van de debugger. Hij vind blijkbaar je implementatie van IPlugin wel. Doe de cast niet en kijk het object met de debugger (en het type ervan met GetType()). Dan zie je in ieder geval uit welke assembly dingen komen, etc. Kijk ook even of geldt dat: obj.GetType() == typeof(IPlugin). Dit zou moeten gelden als je de juiste interface gebruikt.

[ Voor 33% gewijzigd door Infinitive op 03-08-2004 18:26 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • whoami
  • Registratie: December 2000
  • Laatst online: 29-11 22:54
Krijg je trouwens een InvalidCastException of een FileNotFoundException?

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 29-11 22:54
Je zult toch de public key token moeten specifieren in je CreateInstance denk ik.

https://fgheysels.github.io/


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 16:53
whoami schreef op 03 augustus 2004 @ 19:31:
Krijg je trouwens een InvalidCastException of een FileNotFoundException?
InvalidCastException

  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 16:53
whoami schreef op 03 augustus 2004 @ 18:16:
Heb je die gesignde assembly in de GAC geinstalleerd?
Toon eens de code mbt Activator.CreateInstance. Ik geloof dat je daar ook het versie-nr enzo zult moeten mee opgeven.
Nee, de reden voor 't signen is het feit dat wij FxCop 1.3 gebruiken; deze vereist signing; GAC is alleen nuttig voor shared assemblies en die heb ik nog niet.

  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 16:53
whoami schreef op 03 augustus 2004 @ 21:23:
Je zult toch de public key token moeten specifieren in je CreateInstance denk ik.
was ook mijn idee eigenlijk, wat kan het beste doorgeven dan (voorbeeld ?)

  • whoami
  • Registratie: December 2000
  • Laatst online: 29-11 22:54
Zoiets misschien:
code:
1
MyClass t = (MyClass)Activator.CreateInstance ("AssemblyName, version, Culture, PublicKeyToken", "AssemblyName.ClassName");

https://fgheysels.github.io/


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 16:53
whoami schreef op 03 augustus 2004 @ 22:55:
Zoiets misschien:
code:
1
MyClass t = (MyClass)Activator.CreateInstance ("AssemblyName, version, Culture, PublicKeyToken", "AssemblyName.ClassName");
Ik pak de draad even weer op, ben ff met wat anders bezig geweest:

Ik heb een plug in loader gemaakt die dynamisch vanaf de opgegeven folder (via de arguments bij het opstart project) de dll's (assemblies) laadt.

Ik heb een routine gemaakt die elke dll in de opgegeven folder als assembly laadt:

code:
1
Assembly.LoadFrom(file)


Verder heb ik elke assembly gesigned.

Ik krijg een invalid type cast exception. Als ik de signing uit zet, dan gaat het wel goed.

Het probleem is dat assembly probing (het zoeken naar de assemblies) lastig is
als je laadt vanaf een andere locatie dan waar je de applicatie van start (je app. domain zit vast op de plek waar je het opstartproject hebt).

Heeft iemand hier een oplossing voor ?

  • whoami
  • Registratie: December 2000
  • Laatst online: 29-11 22:54
Je kan misschien met de AssemblyResolve event aan de slag gaan.
Deze event wordt getriggered als de runtime je assembly niet kan vinden. In de eventhandler die je dan schrijft kan je zelf gaan aangeven waar hij die assembly moet zoeken, en 'm loaden.
Voor meer info, check de doc's eens.

[rml][ .NET] Dynamisch laden van assemblies[/rml]

https://fgheysels.github.io/

Pagina: 1