2015-04-18 10 views
6

Il progetto A utilizza log4net 1.2.13.0 e dipende dalla libreria B, che utilizza log4net 1.2.11.0. Se lo faccio Package Manager Console> Add-BindingRedirect, ottengo un corretto reindirizzamento obbligatorio in app.config:Quando è necessario utilizzare i reindirizzamenti di binding?

<dependentAssembly> 
    <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" /> 
    <bindingRedirect oldVersion="0.0.0.0-1.2.13.0" newVersion="1.2.13.0" /> 
    </dependentAssembly> 

ho pensato che questo è richiesto in ordine per la costruzione da completare. Ma build riesce anche senza il reindirizzamento. Ecco quello che vedo in log di compilazione (di dettaglio impostato dettagliata):

unificata di riferimento primario "log4net, Version = 1.2.13.0, Culture = neutral, PublicKeyToken = 669e0ddf0bb1aa2a". Utilizzare questa versione invece della versione originale "1.2.11.0" in "C: \ Users \ vorou ​​\ code \ ConsoleApplication1 \ packages \ LibraryB.dll" perché AutoUnify è "true".

Di cosa tratta AutoUnify? Quale è meglio, cioè ci sono dei vantaggi nell'avere un reindirizzamento esplicito in .config?

Inoltre, come posso ricordare, in alcuni casi è necessario per aggiungere reindirizzamenti vincolanti. Altrimenti l'applicazione esploderà in fase di runtime. Quali sono questi casi e perché la magia AutoUnify non funziona per loro?


UPD Ecco un estratto dal MSDN su AutoUnify:

Questo parametro viene utilizzato per le assemblee da costruzione, come le DLL, che non possono avere un file app.config normale. Se true, il grafico delle dipendenze risultante viene automaticamente trattato come se un file App.Config fosse passato al parametro AppConfigFile. Questo file App.Config virtuale ha una voce bindingRedirect per ciascun set di assembly in conflitto, in modo che venga scelto l'assembly della versione più alta. Una conseguenza di ciò è che non ci sarà mai un avvertimento riguardo alle assemblee in conflitto poiché ogni conflitto sarà stato risolto.

Sembra che i reindirizzamenti in .config non abbiano alcun ruolo nel mio caso. Il problema è che la libreria B non può soddisfare le sue dipendenze, e AutoUnify risolve il problema con la regola "fingere che ci siano reindirizzamenti vincolanti".

risposta

10

Il controllo delle versioni è un argomento importante, non può renderlo giustizia in un singolo post SO. Velocità di break-neck:

Questi tipi di shenanigans sono necessari quando si utilizzano più pacchetti Nuget e hanno una dipendenza comune. Come log4net o NewtonSoft.Json, librerie molto comuni che non dispongono di un programma di installazione che inserisce l'assembly nel GAC.

Il problema è che è molto probabile che ogni pacchetto Nuget sia creato con una versione diversa di queste librerie di supporto di base. E un tale pacchetto è improbabile che abbia abbastanza aggiornamenti per mantenere la corrente con l'ultima versione, l'autore del pacchetto favorisce la versione con cui ha testato il suo codice. Quindi ti ritroverai facilmente con un assembly nella tua directory build che richiede 1.2.11.0 e un altro che richiede 1.2.13.0

Che non può funzionare. Il CLR insiste su un esatto corrispondenze versione quando carica un assembly. E deve caricarlo dalla directory di costruzione e non può fare affidamento sul GAC per fornirli.Può esserci solo una copia della DLL, inevitabilmente una delle librerie del pacchetto otterrà la versione sbagliata e il programma si bloccherà. Non va bene, hai un problema che non puoi risolvere senza una ricostruzione del pacchetto Nuget.

Questo è ciò che risolve il reindirizzamento di binding. Ha solo un effetto in fase di esecuzione, non tempo di costruzione. Indica al CLR, "se richiede 1.2.11.0, allora carica semplicemente 1.2.13.0 o, più in generale, con questo specifico reindirizzamento di binding:" se richiede qualsiasi versione inferiore a 1.2.13.0 ". Problema risolto, no crash più le dita Incrociamo il fatto che il pacchetto funziona ancora con quella versione più recente.Essi fanno abbastanza comunemente quando solo il numero di revisione è diverso.Non è tuttavia una garanzia certa

Un'altra cosa che deve essere decisa, questo succede al momento della compilazione, è la versione specifica della libreria che deve essere selezionata. Vuoi 1.2.11.0 o 1.2.13.0? Ecco cosa fa AutoUnify. Niente di molto complicato, seleziona la versione più alta.

+0

Se abbiamo A -> C (v2. 1) e B -> C (v2.2) perché non trattare le dipendenze di A e B come le proprie busines S? (Perché CLR ecc ...) ma ancora perché CLR sta forzando un simile vincolo? Grazie! –

+1

Il CLR non ha questo vincolo. Hai due file denominati C.dll, c'è solo un posto dove puoi metterli in modo che non si sovrascrivano l'un l'altro. Non usarlo –

+0

Qui mi manca la conoscenza, ma perché C deve essere esposto a partire da A, e B. A e B devono essere dll indipendenti/autonomi. (Non sto discutendo voglio solo capire meglio il "perché"). Grazie per la vostra pazienza –

Problemi correlati