L’utilizzo di diverse versioni della stessa assemblea nella stessa cartella

Ho la seguente situazione

Progetto Di Un

 - Uses Castle Windsor v2.2
 - Uses Project B via WindsorContainer

Progetto B

 - Uses NHibernate
 - Uses Castle Windsor v2.1

Nella cartella bin del Progetto ho la dll Castle.DynamicProxy2.dll v2.2 e NHibernate dll. Ora il problema è che NHibernate è dipendente Castle.DynamicProxy2.dll v2.1 che non c’è. Come posso risolvere questa situazione.

  • Non riesco a credere che .rete fa un brutto lavoro alla gestione delle dipendenze e delle collisioni. Microsoft andare a guardare come nodo gestisce i suoi moduli e copia di quel modello!

 

4 Replies
  1. 90

    Ho utilizzato la seguente configurazione per risolvere il problema.

    <configuration>
        <runtime>
            <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
                <dependentAssembly>
                    <assemblyIdentity name="Castle.DynamicProxy2" publicKeyToken="407dd0808d44fbdc" />
                    <codeBase version="2.1.0.0" href="v2.1\Castle.DynamicProxy2.dll" />
                    <codeBase version="2.2.0.0" href="v2.2\Castle.DynamicProxy2.dll" />
                </dependentAssembly>
                <dependentAssembly>
                    <assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" />
                    <codeBase version="1.1.0.0" href="v2.1\Castle.Core.dll" />
                    <codeBase version="1.2.0.0" href="v2.2\Castle.Core.dll" />
                </dependentAssembly>
            </assemblyBinding>
        </runtime>
    </configuration>
    
    • Si potrebbe rispondere stackoverflow.com/questions/1744543/… esattamente con questa risposta.
    • Dove sono le dll posto? È in cartelle denominate v2.1 e v2.2 nella root del sito? Si può mettere la dll nella sottodirectory nella cartella bin?
    • +1 per l’unica risorsa che ha un lavoro <codeBase> soluzione. Jan, il file può essere ovunque, solo xcopy loro e regolare i nomi dei file.
    • Prima volta che vedo che il nome senza estensione dll.
    • In questo esempio, in cui sono le dll relativamente all’applicazione di root?
    • bindingRedirect dovrebbe funzionare anche Solo per riferimento : stackoverflow.com/a/4452193/837623
    • per il sito href dovrebbe iniziare con “bin\” per esempio <codeBase version=”1.0.0.0″ href=”bin\folder\namedll.dll” />
    • Per chiarire @MoslemBenDhaou suggerimento, bindingRedirect è utile se il “Progetto B” funzioni correttamente con v2.2; ha solo bisogno di essere detto di usare v2.2 invece della versione (v2.1) è stato costruito con. Se per qualche motivo “Progetto B” deve utilizzare esattamente v2.1, quindi utilizzare il dual codeBase approccio indicato nella risposta qui. NOTA questa risposta – per due basi di codice di lavoro, assemblee deve essere forte di nome.

  2. 9

    Una soluzione (o la soluzione) sarebbe quello di installare entrambe le versioni in Global Assembly Cache (GAC) sulla macchina(s) su cui il software deve eseguire, e il riferimento all’assembly utilizzando i loro nomi sicuri. Questo presuppone che le assemblee, infatti, hanno una forte nomi.

    Installazione nella GAC sarà un dolore se si dispone di più di un paio di sviluppatori o se si prevede di distribuire la soluzione di molti computer (ad esempio come applicazione per l’utente finale). In questo caso, credo (ma posso sbagliarmi) che l’unica opzione possibile è unione delle due versioni in assemblea, posto che versione. Nel tuo caso specifico, è necessario Castle.DynamicProxy2.dll v2.1 unita nel NHibernate.dll.

    È possibile utilizzare uno strumento chiamato ILMerge di unire le assemblee. Il comando sarà necessario eseguire assomiglia a questo (non testato):

    ILMerge /t:library /internalize /out:Deploy/NHibernate.dll
        NHibernate.dll Castle.DynamicProxy2.dll
    

    Il /internalize interruttore dice ILMerge per segnare tutti i tipi dall’assemblea in seconda convocazione, il Castello (in questo caso) internal in uscita assieme. Senza questo, si potrebbe ottenere errori di compilazione quando si tenta di compilare un progetto di riferimento sia per il tuo nuovo NHibernate.dll e il ripiano versione di Castle.DynamicProxy2.dll v2.2, in quanto essi contengono le classi con lo stesso nome.

  3. 9

    Una cosa molto, molto, molto importante che si potrebbe perdere se non è abbastanza attenzione.

    L’assemblea si scrive nel codeBase tag di versione, deve essere forte il nome.

    Dal seguente link: http://msdn.microsoft.com/en-us/library/efs781xb.aspx

    Per gli assiemi senza un nome forte, versione viene ignorato e il
    loader usi la prima apparizione di <codebase> all’interno
    <dependentAssembly>. Se c’è una voce nell’applicazione
    file di configurazione che reindirizza associazione ad un’altra assemblea, il
    reindirizzamento avrà la precedenza, anche se la versione dell’assembly non
    partita la richiesta di associazione.

  4. 2

    Non credo Hemanshu Bhojak’ soluzione è buona, come non si desidera caricare due versioni della stessa assemblea nello stesso contesto. Questo articolo spiega perché:

    http://msdn.microsoft.com/en-us/library/dd153782.aspx#avoid_loading_multiple_versions

    • Anche se a volte è necessario (o anche forzato) per farlo.
    • Funziona bene sulla mia macchina, e non c’è alcun errore di casting o metodo non trovato. Dopo tutto, GAC inoltre di caricare più versioni di uno stesso gruppo di riferimento. C’è qualcosa di sbagliato con la documentazione.
    • Penso che la documentazione a cui si fa riferimento riguarda manualmente caricamento assemblee di te con l’Assemblea.Di carico, etc.; non sembrano riguardare la .NET fusione caricatore di fare la sua propria cosa. Per esempio, l’articolo è completamente corretto che se si dovesse caricare a livello di programmazione A.dll v1.0 in il dominio di applicazione, e poi in seguito il codice che usi A.dll v1.1, allora si avrà probabilmente avere una brutta giornata

Lascia un commento