Compartir a través de


Reenvío de tipos en Common Language Runtime

El reenvío de tipos permite mover un tipo a otro ensamblado sin tener que volver a compilar las aplicaciones que usan el ensamblado original.

Por ejemplo, supongamos que una aplicación usa la Example clase en un ensamblado denominado Utility.dll. Los desarrolladores de Utility.dll podrían decidir refactorizar el ensamblado y, en el proceso, podrían mover la Example clase a otro ensamblado. Si la versión anterior de Utility.dll se reemplaza por la nueva versión de Utility.dll y su ensamblado complementario, se produce un error en la aplicación que usa la Example clase porque no encuentra la Example clase en la nueva versión de Utility.dll.

Los desarrolladores de Utility.dll pueden evitarlo reenviando solicitudes para la Example clase mediante el TypeForwardedToAttribute atributo . Si el atributo se ha aplicado a la nueva versión de Utility.dll, las solicitudes de la Example clase se reenvieron al ensamblado que ahora contiene la clase . La aplicación existente sigue funcionando normalmente, sin volver a compilar.

Reenvío de un tipo

Hay cuatro pasos para reenviar un tipo:

  1. Mueva el código fuente del tipo del ensamblado original al ensamblado de destino.

  2. En el ensamblado en el que solía estar ubicado el tipo, agregue un atributo TypeForwardedToAttribute para el tipo que se ha movido. En el código siguiente se muestra el atributo de un tipo denominado Example que se movió.

     [assembly:TypeForwardedToAttribute(Example::typeid)]
    
     [assembly:TypeForwardedToAttribute(typeof(Example))]
    
  3. Compile el ensamblaje que ahora contiene el tipo.

  4. Vuelva a compilar el ensamblado donde el tipo solía ubicarse, con una referencia al ensamblado que ahora contiene el tipo. Por ejemplo, si va a compilar un archivo de C# desde la línea de comandos, use la opción Referencias (opciones del compilador de C#) para especificar el ensamblado que contiene el tipo. En C++, use la directiva #using en el archivo de origen para especificar el ensamblado que contiene el tipo.

Ejemplo de reenvío de tipos de C#

Continuando con la descripción de ejemplo artificioso anterior, imagine que está desarrollando el Utility.dll y tiene una clase Example. Utility.csproj es una biblioteca de clases básica:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsing>true</ImplicitUsing>
  </PropertyGroup>

</Project>

La Example clase proporciona algunas propiedades e invalida Object.ToString:

using System;

namespace Common.Objects;

public class Example
{
    public string Message { get; init; } = "Hi friends!";

    public Guid Id { get; init; } = Guid.NewGuid();

    public DateOnly Date { get; init; } = DateOnly.FromDateTime(DateTime.Today);

    public sealed override string ToString() =>
        $"[{Id} - {Date}]: {Message}";
}

Ahora imagínese que hay un proyecto de consumo y se representa en el ensamblado Consumer. Este proyecto de consumo hace referencia al ensamblado Utility. Por ejemplo, crea una instancia del Example objeto y lo escribe en la consola en su archivo Program.cs :

using System;
using Common.Objects;

Example example = new();

Console.WriteLine(example);

Cuando se ejecuta la aplicación de consumo, generará el estado del Example objeto . En este momento, no hay reenvío de tipos, ya que Consuming.csproj hace referencia a Utility.csproj. Sin embargo, el desarrollador del ensamblado de la utilidad decide quitar el Example objeto como parte de una refactorización. Este tipo ha sido movido a un Common.csproj recién creado.

Al quitar este tipo del ensamblado Utility, los desarrolladores están introduciendo un cambio rupturista. Todos los proyectos de consumo se interrumpirán cuando se actualicen al ensamblado Utility más reciente.

En lugar de exigir que los proyectos de consumo agreguen una nueva referencia al ensamblado Common, puede reenviar el tipo. Dado que este tipo se eliminó del ensamblado Utility, deberá referenciar Utility.csproj a Common.csproj:

<ItemGroup>
  <ProjectReference Include="..\Common\Common.csproj" />
</ItemGroup>

El proyecto de C# anterior ahora hace referencia al ensamblado Común recién creado. Puede ser PackageReference o ProjectReference. El ensamblado Utility debe proporcionar la información de reenvío de tipos. Por convención, las declaraciones de reenvío de tipo normalmente se encapsulan en un único archivo denominado TypeForwarders, considere el archivo de C# TypeForwarders.cs en el ensamblado Utility :

using System.Runtime.CompilerServices;
using Common.Objects;

[assembly:TypeForwardedTo(typeof(Example))]

El ensamblaje Utility hace referencia al ensamblaje Common y reenvía el tipo Example. Si va a compilar el ensamblado Utility con las declaraciones de reenvío de tipos y va a colocar Utility.dll en el contenedor Consuming, la aplicación de consumo funcionará sin compilarse.

Consulte también