2012-06-14 41 views
9

Come può un singolo assieme .NET, con targeting 2.0, 3.0, 3.5, 4.0 e 4.5, supportare i metodi di estensione per i consumatori C# e VB.NET?Escape Catch-22 con attributi di estensione in .NET 2.0

Il suggerimento standard è di aggiungere questo:

namespace System.Runtime.CompilerServices 
{ 
    public sealed class ExtensionAttribute : Attribute { } 
} 

Questo l'approccio suggerito da more di one Microsoft employee ed è stato anche descritto in MSDN magazine. È widely chiamato da many bloggers come "senza effetti negativi".

Oh, tranne che causerà un errore del compilatore da un progetto VB.NET che ha come target .NET 3.5 o versione successiva.

Gli autori di Microsoft.Core.Scripting.dll figured it out e modificato "pubblico" in "interno".

namespace System.Runtime.CompilerServices 
{ 
    internal sealed class ExtensionAttribute : Attribute { } 
} 

che sembrava risolvere il problema di compatibilità VB.

Quindi ho usato con fiducia questo approccio per l'ultima versione (3.2.1) di widely-used ImageResizing.Net library.

Ma poi, abbiamo iniziare a ricevere questo errore del compilatore (original report), più o meno casualmente, per alcuni utenti mirati .NET 3.5+.

Error 5 Missing compiler required member 
'System.Runtime.CompilerServices.ExtensionAttribute..ctor' 

Poiché il/VisualStudio compilatore MSBuild a quanto pare non si preoccupa di guardare regole di visibilità per la risoluzione conflitti di denominazione, e l'ordine di riferimenti di assemblaggio svolge un ruolo non del tutto docuemented, non pienamente capisco perché e quando ciò accade

Ci sono uno few hacky workarounds, come cambiare lo spazio dei nomi dell'assieme, ricreare il file di progetto, eliminare/leggere System.Core e giocherellare con la versione di destinazione del framework .NET. Sfortunatamente, nessuno di questi workaround è al 100% (eccetto l'aliasing, ma è un dolore inaccettabile).

Come posso risolvere questo mentre

  1. Mantenere il supporto per l'utilizzo metodo di estensione all'interno del gruppo,
  2. Mantenere il supporto per .NET 2.0/3.0
  3. Non richiedendo più assembly per ogni versione di .NET framework .

Oppure, esiste un hotfix per fare in modo che il compilatore presti attenzione alle regole di scoping?

Domande correlate, in modo che non rispondono a questa domanda

+0

Ugh. La tua taglia manca uno zero. Meglio affidarsi a questo supporto con Microsoft, anche se è probabile che lo eliminino con "non supportato". –

risposta

1

Abbiamo avuto lo stesso problema con IronPython. http://devhawk.net/2008/10/21/the-fifth-assembly/

Abbiamo finito per spostare la nostra versione personalizzata di ExtensionAttribute al proprio assembly. In questo modo, i clienti potevano scegliere tra referenziare il nostro assembly ExtensionAttribute personalizzato o System.Core, ma mai entrambi!

L'altra cosa complicata è che devi sempre distribuire l'assembly ExtensionAttribute, anche se non lo fai riferimento nel tuo progetto. Gli assembly di progetto che espongono i metodi di estensione avranno un assemblyref per quell'assembly ExtensionAttribute personalizzato, pertanto CLR si arrabbia se non può essere trovato.

Dato il duro requisito del supporto .NET 2.0, penserei che la soluzione migliore sarebbe semplicemente non utilizzare affatto i metodi di estensione. Non ho familiarità con il progetto ImageResizer, ma sembra che questo sia stato un recente cambiamento in ImageResizer. Quanto è fattibile modificare i metodi di estensione ai metodi statici tradizionali? In realtà abbiamo pensato a questo per IronPython/DLR, ma non era fattibile (ci siamo uniti a LINQ a quel punto e LINQ aveva fatto un uso massiccio dei metodi di estensione essenzialmente per la sua intera esistenza).

+0

Grazie per aver aggiornato l'articolo con un link! Penso che Newtonsoft.Json abbia avuto lo stesso incubo che abbiamo fatto ... Troppi blog là fuori dicono che non ci sono ripercussioni, e quando ho letto lo stesso fatto indiscusso su una mezza dozzina di blog ho pensato che fosse vero! –

+0

Solo un'idea, potremmo andare in giro con l'inoltro del tipo in qualche modo? –

+0

Avremmo ancora bisogno di più versioni dell'assieme ... –