Partilhar via


Encaminhamento de tipos no ambiente de execução de linguagem comum

O encaminhamento de tipo permite mover um tipo para outro assembly sem ter que recompilar aplicativos que usam o assembly original.

Por exemplo, suponha que um aplicativo use a Example classe em um assembly chamado Utility.dll. Os desenvolvedores do Utility.dll podem decidir refatorar o assembly e, no processo, podem mover a Example classe para outro assembly. Se a versão antiga do Utility.dll for substituída pela nova versão do Utility.dll e seu assembly complementar, o aplicativo que usa a Example classe falhará porque não é possível localizar a Example classe na nova versão do Utility.dll.

Os desenvolvedores do Utility.dll podem evitar isso encaminhando solicitações para a Example classe, usando o TypeForwardedToAttribute atributo . Se o atributo tiver sido aplicado à nova versão do Utility.dll, as solicitações para a Example classe serão encaminhadas para o assembly que agora contém a classe. A aplicação existente continua a funcionar normalmente, sem recompilação.

Reenviar um tipo

Há quatro etapas para encaminhar um tipo de dados:

  1. Mova o código-fonte do tipo do conjunto original para o conjunto de destino.

  2. No assembly onde o tipo costumava estar localizado, adicione um TypeForwardedToAttribute para o tipo que foi realocado. O código a seguir mostra o atributo para um tipo chamado Example que foi movido.

     [assembly:TypeForwardedToAttribute(Example::typeid)]
    
     [assembly:TypeForwardedToAttribute(typeof(Example))]
    
  3. Compile a assemblagem que agora contém o tipo.

  4. Recompile a assemblagem onde o tipo estava localizado, com uma referência à assemblagem que agora contém o tipo. Por exemplo, se você estiver compilando um arquivo C# a partir da linha de comando, use a opção Referências (opções do compilador C#) para especificar o assembly que contém o tipo. Em C++, use a diretiva #using no arquivo de origem para especificar o assembly que contém o tipo.

Exemplo de redirecionamento de tipos em C#

Continuando a partir da descrição de exemplo inventada acima, imagine que você está desenvolvendo o Utility.dll, e você tem uma Example classe. O Utility.csproj é uma biblioteca de classes básica:

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

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

</Project>

A Example classe fornece algumas propriedades e substitui: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}";
}

Agora, imagine que existe um projeto consumidor e ele está representado na Consumer assembly. Este projeto de consumo faz referência ao assembly Utility. Como exemplo, ele instancia o Example objeto e o grava no console em seu arquivo Program.cs :

using System;
using Common.Objects;

Example example = new();

Console.WriteLine(example);

Quando o aplicativo de consumo é executado, ele produz o estado do Example objeto. Neste ponto, não há encaminhamento de tipo, pois o Consuming.csproj faz referência ao Utility.csproj. No entanto, os desenvolvedores do assembly Utility decidem remover o Example objeto como parte de uma refatoração. Esse tipo é movido para um Common.csproj recém-criado.

Ao remover esse tipo do Assembly Utility, os desenvolvedores estão introduzindo uma alteração significativa. Todos os projetos dependentes serão interrompidos quando forem atualizados para a compilação mais recente do Utility.

Em vez de exigir que os projetos consumidores adicionem uma nova referência ao assembly Common, você pode encaminhar o tipo. Como esse tipo foi removido do assembly Utility, você precisará referenciar o Utility.csproj ao Common.csproj:

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

O projeto C# anterior agora faz referência ao assembly comum recém-criado. Pode ser um PackageReference ou um ProjectReference. O assembly Utility precisa fornecer as informações de encaminhamento do tipo. Por convenção, as declarações de encaminhamento geralmente são encapsuladas em um único arquivo chamado TypeForwarders, considere o seguinte arquivo C# TypeForwarders.cs no assembly Utility:

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

[assembly:TypeForwardedTo(typeof(Example))]

O assembly Utility faz referência ao assembly Common e encaminha o tipo Example. Se compilar o assembly Utility com as declarações de encaminhamento de tipo e soltar o Utility.dll no binário Consuming, o aplicativo de consumo funcionará sem ser compilado.

Ver também