Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los ensamblados de referencia son un tipo especial de ensamblado que solo contiene la cantidad mínima de metadatos necesarios para representar la superficie de API pública de la biblioteca. Incluyen declaraciones para todos los miembros que son significativos al hacer referencia a un ensamblado en las herramientas de compilación, pero excluyen todas las implementaciones de miembros y las declaraciones de miembros privados que no tienen ningún impacto observable en su contrato de API. Por el contrario, los ensamblados normales se denominan ensamblados de implementación.
Los ensamblados de referencia no se pueden cargar para su ejecución, pero se pueden pasar como entrada del compilador de la misma manera que los ensamblados de implementación. Normalmente, los ensamblados de referencia se distribuyen con el Kit de desarrollo de software (SDK) de una plataforma o biblioteca determinada.
El uso de un ensamblado de referencia permite a los desarrolladores compilar programas destinados a una versión de biblioteca específica sin tener el ensamblado de implementación completo para esa versión. Supongamos que solo tiene la versión más reciente de alguna biblioteca en la máquina, pero quiere compilar un programa destinado a una versión anterior de esa biblioteca. Si compila directamente en el ensamblado de implementación, es posible que use accidentalmente miembros de API que no estén disponibles en la versión anterior. Solo encontrará este error al probar el programa en la máquina de destino. Si compila con el ensamblado de referencia para la versión anterior, obtendrá inmediatamente un error en tiempo de compilación.
Un ensamblado de referencia también puede representar un contrato, es decir, un conjunto de API que no corresponden al ensamblado de implementación concreto. Estos ensamblados de referencia, denominados ensamblados de contrato, se pueden usar para tener como destino varias plataformas que admiten el mismo conjunto de API. Por ejemplo, .NET Standard proporciona el ensamblado de contrato, netstandard.dll, que representa el conjunto de API comunes compartidas entre distintas plataformas .NET. Las implementaciones de estas API se incluyen en ensamblados diferentes en distintas plataformas, como mscorlib.dll en .NET Framework o System.Private.CoreLib.dll en .NET Core. Una biblioteca destinada a .NET Standard se puede ejecutar en todas las plataformas que admiten .NET Standard.
Uso de ensamblados de referencia
Para usar determinadas APIs de su proyecto, tiene que agregar referencias a sus ensamblados. Puede agregar referencias a ensamblados de implementación o a ensamblados de referencia. Se recomienda usar ensamblados de referencia siempre que estén disponibles. Al hacerlo, se asegura de que solo use los miembros de API admitidos en la versión de destino, destinados a ser usados por los diseñadores de API. El uso del ensamblado de referencia garantiza que no está tomando una dependencia de los detalles de implementación.
Los ensamblados de referencia de las bibliotecas de .NET Framework se distribuyen con paquetes de destino. Para obtenerlos, descargue un instalador independiente o seleccione un componente en el instalador de Visual Studio. Para obtener más información, consulte Instalación de .NET Framework para desarrolladores. En el caso de .NET Core y .NET Standard, los ensamblados de referencia se descargan automáticamente según sea necesario (a través de NuGet) y se referencian. Para .NET Core 3.0 y versiones posteriores, los ensamblados de referencia para el marco principal se encuentran en el paquete Microsoft.NETCore.App.Ref (el paquete de Microsoft.NETCore.App se usa en su lugar para las versiones anteriores a la 3.0).
Al agregar referencias a ensamblados de .NET Framework en Visual Studio mediante el cuadro de diálogo Agregar referencia , se selecciona un ensamblado de la lista y Visual Studio busca automáticamente ensamblados de referencia que corresponden a la versión de la plataforma de destino seleccionada en el proyecto. Lo mismo se aplica a la adición de referencias directamente en el proyecto de MSBuild mediante el elemento de proyecto Referencia : solo tiene que especificar el nombre del ensamblado, no la ruta de acceso de archivo completa. Al agregar referencias a estos ensamblados en la línea de comandos mediante la -reference
opción del compilador (en C# y en Visual Basic) o mediante el Compilation.AddReferences método de la API de Roslyn, debe especificar manualmente los archivos de ensamblado de referencia para la versión correcta de la plataforma de destino. Los archivos de ensamblado de referencia de .NET Framework se encuentran en el %ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\.NETFramework directorio. Para .NET Core, puede forzar la operación de publicación para que copie los ensamblados de referencia para su plataforma de destino en el subdirectorio publish/refs del directorio de salida estableciendo la propiedad del proyecto PreserveCompilationContext
a true
. A continuación, puede pasar estos archivos de ensamblado de referencia al compilador. Utilizar el paquete DependencyContext
puede ayudar a localizar sus rutas.
Dado que no contienen ninguna implementación, los ensamblados de referencia no se pueden cargar para su ejecución. Si intenta hacerlo, se producirá una excepción System.BadImageFormatException. Si quiere examinar el contenido de un ensamblado de referencia, puede cargarlo en el contexto de solo reflexión en .NET Framework (mediante el método Assembly.ReflectionOnlyLoad) o en el contexto MetadataLoadContext en .NET y .NET Framework.
Generación de ensamblados de referencia
Puede ser útil generar ensamblados de referencia para las bibliotecas cuando los clientes de estas necesiten compilar sus programas en muchas versiones diferentes de las bibliotecas. La distribución de ensamblados de implementación para todas estas versiones podría ser poco práctico debido a su tamaño grande. Los ensamblados de referencia son más pequeños y su distribución como parte del SDK de la biblioteca reduce el tamaño de descarga y ahorra espacio en disco.
Los IDE y las herramientas de compilación también pueden aprovechar los ensamblados de referencia para reducir los tiempos de compilación en caso de soluciones grandes que constan de varias bibliotecas de clases. Normalmente, en escenarios de compilación incremental, se vuelve a generar un proyecto cuando se cambia cualquiera de sus archivos de entrada, incluidos los ensamblados de los que depende. El ensamblado de implementación cambia cada vez que el programador cambia la implementación de cualquier miembro. El ensamblado de referencia solo cambia cuando se ve afectado su API pública. Por lo tanto, el uso del ensamblado de referencia como archivo de entrada en lugar del ensamblado de implementación permite omitir la compilación del proyecto dependiente en algunos casos.
Puede generar ensamblados de referencia:
- En un proyecto de MSBuild, mediante la
ProduceReferenceAssembly
propiedad de proyecto. - Al compilar el programa desde la línea de comandos, especificando
-refonly
las opciones del compilador (C# / Visual Basic ) o-refout
(C# / Visual Basic). - Al usar la API de Roslyn, al establecer EmitOptions.EmitMetadataOnly a
true
y EmitOptions.IncludePrivateMembers afalse
en un objeto pasado al método Compilation.Emit.
Si desea distribuir ensamblados de referencia con paquetes NuGet, debe incluirlos en el subdirectorio ref\ en el directorio del paquete en lugar de en el subdirectorio lib\ usado para ensamblados de implementación.
Estructura de ensamblados de referencia
Los ensamblados de referencia son una expansión del concepto relacionado, los ensamblados de solo metadatos. Los ensamblados de solo metadatos tienen sus cuerpos de métodos reemplazados por un cuerpo throw null
único, pero incluyen todos los miembros excepto los tipos anónimos. El motivo de usar cuerpos throw null
(en lugar de no usar ningún cuerpo) es que PEVerify pueda ejecutar y pasar (y, por lo tanto, validar la integridad de los metadatos).
Los ensamblados de referencia también quitan los metadatos (miembros privados) de los ensamblados de solo metadatos:
- Un ensamblado de referencia solo tiene referencias para lo que necesita en la superficie de API. El ensamblado real puede tener referencias adicionales relacionadas con implementaciones específicas. Por ejemplo, el ensamblado de referencia para
class C { private void M() { dynamic d = 1; ... } }
no hace referencia a ningún tipo necesario paradynamic
. - Los miembros de funciones privadas (métodos, propiedades y eventos) se eliminan en los casos en los que su eliminación no afecta de manera observable a la compilación. Si no hay atributos InternalsVisibleTo, también se eliminan los miembros de función internos.
Los metadatos de los ensamblados de referencia siguen manteniendo la siguiente información:
- Todos los tipos, incluidos los tipos privados y anidados.
- Todos los atributos, incluso los internos.
- Todos los métodos virtuales.
- Implementaciones de interfaz explícitas.
- Eventos y propiedades implementados explícitamente, ya que sus descriptores de acceso son virtuales.
- Todos los campos de estructuras.
Los ensamblados de referencia incluyen un atributo ReferenceAssembly de nivel de ensamblado. Este atributo se puede especificar en el origen; a continuación, el compilador no tendrá que sintetizarlo. Debido a este atributo, los tiempos de ejecución rechazarán cargar ensamblados de referencia para su ejecución (pero pueden cargarse en modo de solo reflexión).
Los detalles exactos de la estructura del ensamblado de referencia dependen de la versión del compilador. Las versiones más recientes pueden optar por excluir más metadatos si se determina que no afecta a la superficie de API pública.
Nota:
La información de esta sección solo se aplica a los ensamblados de referencia generados por los compiladores de Roslyn a partir de la versión 7.1 de C# o visual Basic versión 15.3. La estructura de ensamblados de referencia para las bibliotecas de .NET Framework y .NET Core puede diferir en algunos detalles, ya que usan su propio mecanismo de generación de ensamblados de referencia. Por ejemplo, podrían tener cuerpos de método totalmente vacíos en lugar del cuerpo throw null
. Pero el principio general sigue siendo aplicable: no tienen implementaciones de método utilizables y contienen metadatos solo para los miembros que tienen un impacto observable desde una perspectiva de API pública.