2012-06-14 8 views
9

¿Cómo puede un solo ensamblado de .NET, dirigido a 2.0, 3.0, 3.5, 4.0 y 4.5 concurrentemente, soportar métodos de extensión para consumidores C# y VB.NET?Escape Catch-22 con atributos de extensión en .NET 2.0

La sugerencia habitual es añadir lo siguiente:

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

Este enfoque sugerido por more de one Microsoft employee e incluso fue presentado en MSDN magazine. Es widely aclamado por many bloggers como 'sin efectos nocivos'.

Ah, excepto que causará un error de compilación de un proyecto de VB.NET que se dirige a .NET 3.5 o superior.

Los autores de Microsoft.Core.Scripting.dll figured it out, y cambiado 'público' a 'interno'.

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

Lo que pareció resolver el problema de compatibilidad de VB.

Así que confiadamente utilicé ese enfoque para la última versión (3.2.1) del widely-used ImageResizing.Net library.

Pero luego, comenzamos a obtener este error de compilador (original report), de forma más o menos aleatoria, para ciertos usuarios que se orientan a .NET 3.5+.

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

Debido a que el/VisualStudio compilador MSBuild aparentemente no se molesta en mirar a reglas de alcance en la resolución de conflictos de nombres y el orden de las referencias de ensamblado juega un papel docuemented no del todo, no entiendo del todo por qué y cuando esto sucede.

Hay un few hacky workarounds, como cambiar el espacio de nombres del ensamblado, volver a crear el archivo de proyecto, eliminar/leer System.Core y manipular la versión de destino del .NET framework. Desafortunadamente, ninguna de estas soluciones alternativas es 100% (excepto aliasing, pero eso es un dolor inaceptable).

¿Cómo puedo solucionar esto mientras

  1. El mantenimiento de soporte para el uso del método de extensión dentro del conjunto,
  2. mantener el apoyo a .NET 2.0/3.0
  3. No requiere múltiples conjuntos para cada versión del marco .NET .

¿O hay alguna revisión para que el compilador preste atención a las reglas de alcance?

preguntas relacionadas encendido de modo que no responden a esta pregunta

+0

Ugh. Tu recompensa no tiene un cero. Lo mejor es llevar esto a cabo con el Soporte de Microsoft, aunque es probable que lo rechacen con 'no compatible'. –

Respuesta

1

Nos encontramos con el mismo problema con IronPython. http://devhawk.net/2008/10/21/the-fifth-assembly/

Terminamos moviendo nuestra versión personalizada de ExtensionAttribute a su propio conjunto. De esta forma, los clientes podrían elegir entre hacer referencia a nuestro ensamblaje de extensión de aplicaciones personalizado o System.Core, ¡pero nunca a los dos!

El otro inconveniente es que siempre debe implementar el ensamblaje ExtensionAttribute, incluso si no hace referencia a él en su proyecto. Los ensamblados de proyectos que exponen los métodos de extensión tendrán un ensamblaje con ese ensamblaje personalizado de ExtensiónAttributo, por lo que CLR se alterará si no se puede encontrar.

Dado el duro requerimiento de la compatibilidad con .NET 2.0, creo que la mejor opción sería simplemente no usar métodos de extensión. No estoy familiarizado con el proyecto ImageResizer, pero parece que esto fue un cambio reciente en ImageResizer. ¿Qué tan factible sería cambiar los métodos de extensión a métodos estáticos tradicionales? Realmente pensamos en eso para IronPython/DLR, pero no era factible (en ese momento nos fusionamos con LINQ y LINQ había hecho un uso intensivo de los métodos de extensión para, básicamente, toda su existencia).

+0

Gracias por actualizar el artículo con un enlace! Creo que Newtonsoft.Json se encontró con la misma pesadilla que nosotros ... Demasiados blogs dicen que no hay repercusiones, y cuando leí el mismo hecho indiscutible en media docena de blogs, ¡supuse que era verdad! –

+0

Solo idea, ¿podríamos movernos con el reenvío de tipos de alguna manera? –

+0

Todavía necesitaríamos varias versiones del ensamblaje ... –

Cuestiones relacionadas