2009-05-14 5 views
17

Vorrei creare una classe che compili in una singola DLL. Questa DLL aggiungerebbe funzionalità a un prodotto esistente.È possibile avere riferimenti DLL indipendenti dalla versione in una classe?

Per rendere questo lavoro, la classe personalizzata fa riferimento a DLL contenute nel prodotto sottostante. Questi riferimenti sono necessari per la compilazione.

Qui tutto funziona correttamente e le compilazioni di classi personalizzate. Posso rilasciare la DLL prodotta nel prodotto e tutto funziona correttamente.

Tuttavia, questo prodotto ha diverse versioni (versioni secondarie, service pack). Vorrei distribuire questa DLL ad altri, ma sto trovando la DLL deve corrispondere perfettamente la versione del prodotto. Se non c'è una corrispondenza perfetta, quindi verifica il seguente errore:

Impossibile caricare il file o il montaggio 'Product.Web.UI, Version = 3.6.1920.2, Culture = neutral, PublicKeyToken = dfeaee0e3978ac79 'o una delle sue dipendenze. La definizione manifest dell'oggetto ubicata nello non corrisponde al riferimento all'assembly. (Eccezione da HRESULT: 0x80131040)

Come posso produrre una DLL che non è schizzinosi riguardo il riferimento di versione?

risposta

4

Non ho ancora una risposta alla mia domanda, ma userò questa risposta per registrare le briciole di pane che ho trovato durante la ricerca di una soluzione.

ho trovato una domanda in qualche modo correlato su StackOverflow:

Compile a version agnostic .DLL in .NET (Using Manifests?)

non ho la capacità di modificare il prodotto sottostante però, quindi la risposta non funziona per me.


Aggiornato:

ho mandato qualcuno molto più intelligente di me e qui è stata la risposta:

Quando si fa riferimento assembly con nome, da Visual Studio predefinita aggiunge piena riferimento al riferimento montaggio. Ciò significa che include il nome dell'assembly, la versione esatta, la cultura e il token della chiave pubblica. Se nessuna di queste informazioni non corrisponde all'eccezione descritta viene lanciata.

Rimuovere i nomi forti dei nostri assembly non è semplicemente un'opzione. Non entrerò nei dettagli perché, ma puoi fare qualche ricerca su MSDN.

Pertanto, sono disponibili due opzioni per creare soluzioni contro ogni versione degli assiemi a cui si fa riferimento.

  1. Si potrebbe fare riferimento parziale. Vedi questo articolo: http://msdn.microsoft.com/en-us/library/0a7zy9z5(VS.71).aspx.
  2. È possibile dichiarare versioni compatibili con il reindirizzamento dell'associazione nel web.config. Vedi questo articolo: http://msdn.microsoft.com/en-us/library/433ysdt1.aspx.

In generale si consiglia il secondo approccio, perché: 1. Non è possibile usare parziale riferimento assembly nella Global Assembly Cache, il che significa il vostro controllo getterà la stessa eccezione se le assemblee sono nel GAC. 2. Dichiarate esplicitamente versioni compatibili.

-1

In VisualStudio: avete provato a fare clic con il pulsante destro del mouse sull'assieme di riferimento (dll) e quindi selezionare le proprietà e impostare "richiede una versione specifica" (o così) ancora? Questo potrebbe risolvere il tuo problema.

Andreas

+1

Sì, l'ho provato. La mia comprensione è che questa impostazione si applica solo in fase di compilazione. Significato, durante la compilazione il compilatore non è schizzinoso sulla versione della DLL che trova. Tuttavia, per la DLL risultante, tali riferimenti DLL non specifici verranno trasformati in riferimenti di assembly con nome sicuro (completi di numero di versione) in base alla DLL utilizzata per la compilazione. –

7

Questa è una soluzione eccellente. Ha risolto un problema simile per me.

Compile a version agnostic DLL in .NET

Nel caso in cui il collegamento muore mai, la chiave è quello di gestire l'evento AppDomain.CurrentDomain.AssemblyResolve come qui di seguito. L'evento si attiva in qualsiasi momento in cui un binding dell'assembly non riesce, quindi puoi risolverlo da solo, correggendo i conflitti di versione.

using System.Reflection; 

static Program() 
{ 
    AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e) 
    { 
     AssemblyName requestedName = new AssemblyName(e.Name); 

     if (requestedName.Name == "Office11Wrapper") 
     { 
      // Put code here to load whatever version of the assembly you actually have 

      return Assembly.LoadFile("Office11Wrapper.DLL"); 
     } 
     else 
     { 
      return null; 
     } 
    } 
}