2012-12-02 6 views
14

La mia domanda è molto simile a this one, solo che la risposta e la soluzione non funzionano per me. Anche io sono in Visual Studio 2012.VSIX - Impossibile caricare il file o l'assembly di una dll di riferimento

Ho un VSPackage che fa riferimento a un altro progetto, che dipende da altre DLL. Ogni volta che eseguo il mio pacchetto in debug ottengo un'eccezione che non è possibile trovare le altre DLL. Sono nella directory di output e sono firmati.

Ho provato a fare riferimento direttamente al progetto VSPackage senza alcun risultato.

Pensieri?

risposta

29

Questo problema esiste perché Visual Studio non cerca gli assembly in una cartella dell'estensione se l'estensione non ha alcuna dipendenza esplicita da questi assembly. Ad esempio, dipendenze impostate in un file di configurazione (config IoC) o in codice xaml. Conosco tre soluzioni a questo problema:

  1. È possibile distribuire questi assembly nel GAC e Visual Studio li caricherà. Questo metodo è valido se si utilizza una libreria di terze parti creata per l'utilizzo in GAC (ad esempio, MS Enterprise Library). Ma VSIX Deployment Package non consente l'installazione di assembly nel GAC, è possibile utilizzare il programma di installazione MSI.

  2. Per VSPackages per Visual Studio 2010/2012 è possibile utilizzare l'attributo ProvideBindingPath. Il percorso in cui verrà posizionata l'estensione verrà aggiunto ai percorsi utilizzati da Visual Studio per trovare gli assembly dipendenti. Se la tua estensione non include un VSPackage, puoi aggiungere questo attributo a qualsiasi classe pubblica (see here).

    [ProvideBindingPath] 
    public class MyVsPackage : Package 
    { /* ... */ } 
    
  3. È possibile risolvere manualmente i nomi degli assiemi. Per fare ciò, è necessario abbonarsi all'evento AssemblyResolve ed è necessario restituire gli assembly richiesti da un gestore. Questo è il modo più flessibile, se non puoi usare i metodi precedenti, questo è specialmente per te.

    Nel mio progetto IntelliDebugger, ho scritto una ManualAssemblyResolver classe per esso:

using System; 
using System.Reflection; 

namespace IntelliEgg.Debugger.Utility 
{ 
    public class ManualAssemblyResolver : IDisposable 
    { 
     public ManualAssemblyResolver(Assembly assembly) 
     { 
      if (assembly == null) 
       throw new ArgumentNullException("assembly"); 

      _assemblies = new[] {assembly}; 
      AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; 
     } 

     public ManualAssemblyResolver(params Assembly[] assemblies) 
     { 
      if (assemblies == null) 
       throw new ArgumentNullException("assemblies"); 

      if (assemblies.Length == 0) 
       throw new ArgumentException("Assemblies should be not empty.", "assemblies"); 

      _assemblies = assemblies; 
      AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; 
     } 

     public void Dispose() 
     { 
      AppDomain.CurrentDomain.AssemblyResolve -= OnAssemblyResolve; 
     } 

     private Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) 
     { 
      foreach (Assembly assembly in _assemblies) 
      { 
       if (args.Name == assembly.FullName) 
       { 
        return assembly; 
       } 
      } 

      return null; 
     } 

     private readonly Assembly[] _assemblies; 
    } 
} 

Questa classe deve essere creato prima della prima chiamata al gruppo problema (ad esempio, in Package :: Initialize() metodo)

+0

Perfetto. Grazie molto. – Adam

+0

Come sono stati caricati gli assembly per passare a questa classe di utilità? Piuttosto ... quale contesto hai usato? 'Assembly.LoadFrom (nome del file)'? Mi chiedo come si protegge la stessa versione di un assembly da caricare da un altro plugin in un altro contesto? –

+1

Sì, utilizzo 'Assembly.LoadFrom()' o 'typeof (ClassFromMyAssembly) .Assembly' e un riferimento a' MyAssembly' nel progetto (per 'System.Windows.Interactivity.dll'). Lo scopo dell'utilizzo di 'ManualAssemblyResolver' consente a Visual Studio di caricare tutti gli assembly dipendenti da qualsiasi cartella e determinarlo esplicitamente nel codice. Per supportare la modularità, utilizzo MS Prism e configuro il caricamento dei moduli nella classe 'Bootstrapper'. –

Problemi correlati