Freigeben über


Typweiterleitung in der Common Language Runtime

Mit der Typweiterleitung können Sie einen Typ in eine andere Assembly verschieben, ohne dass Anwendungen, die die ursprüngliche Assembly verwenden, neu kompiliert werden müssen.

Angenommen, eine Anwendung verwendet die Klasse in einer Assembly mit dem Example Namen Utility.dll. Die Entwickler von Utility.dll können entscheiden, die Assembly umzugestalten, und im Prozess verschieben sie die Example Klasse in eine andere Assembly. Wenn die alte Version von Utility.dll durch die neue Version von Utility.dll und der zugehörigen Begleitassembly ersetzt wird, schlägt die Anwendung, die die Example Klasse verwendet, fehl, da sie die Klasse in der Example neuen Version von Utility.dllnicht finden kann.

Die Entwickler von Utility.dll können dies vermeiden, indem Anforderungen für die Example Klasse mithilfe des TypeForwardedToAttribute Attributs weitergeleitet werden. Wenn das Attribut auf die neue Version von Utility.dllangewendet wurde, werden Anforderungen für die Example Klasse an die Assembly weitergeleitet, die jetzt die Klasse enthält. Die vorhandene Anwendung funktioniert weiterhin normal, ohne dass sie neu kompiliert wird.

Typ weiterleiten

Es gibt vier Schritte zum Weiterleiten eines Typs:

  1. Verschieben Sie den Quellcode für den Typ von der ursprünglichen Assembly in die Zielassembly.

  2. Fügen Sie in der Assembly, in der sich der Typ früher befand, ein TypeForwardedToAttribute für den verschobenen Typ hinzu. Der folgende Code zeigt das Attribut für einen Typ mit dem Namen Example , der verschoben wurde.

     [assembly:TypeForwardedToAttribute(Example::typeid)]
    
     [assembly:TypeForwardedToAttribute(typeof(Example))]
    
  3. Kompilieren Sie die Assembly, die nun den Typ enthält.

  4. Führen Sie für die Assembly, in der sich der Typ befand, eine Neukompilierung mit einem Verweis auf die Assembly durch, die jetzt den Typ enthält. Wenn Sie beispielsweise eine C#-Datei über die Befehlszeile kompilieren, verwenden Sie die Option "Verweise ( C#-Compileroptionen)" , um die Assembly anzugeben, die den Typ enthält. Verwenden Sie in C++ die #using-Direktive in der Quelldatei, um die Assembly anzugeben, die den Typ enthält.

Beispiel für die C#-Typweiterleitung

Stellen Sie sich vor, Sie entwickeln die Datei Utility.dll und verfügen über eine Example-Klasse. Utility.csproj ist eine grundlegende Klassenbibliothek:

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

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

</Project>

Die Example-Klasse bietet einige Eigenschaften und setzt Object.ToString außer Kraft:

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}";
}

Stellen Sie sich nun vor, dass es ein verarbeitendes Projekt gibt, welches in der Consumer-Assembly vorhanden ist. Dieses verarbeitende Projekt verweist auf die Utility-Assembly. Als Beispiel instanziiert es das Example Objekt und schreibt es in die Konsole in der Program.cs Datei:

using System;
using Common.Objects;

Example example = new();

Console.WriteLine(example);

Wenn die verbrauchende App ausgeführt wird, gibt sie den Status des Example Objekts aus. An diesem Punkt gibt es keine Typweiterleitung, da die Consuming.csproj auf " Utility.csproj" verweist. Die Entwickler der Hilfsprogrammassembly entscheiden sich jedoch, das Example Objekt als Teil einer Umgestaltung zu entfernen. Dieser Typ wird in eine neu erstellte Common.csproj verschoben.

Durch das Entfernen dieses Typs aus der Utility-Assembly führen die Entwickler eine schwerwiegende Änderung ein. Alle verarbeitenden Projekte werden unterbrochen, wenn sie auf die neueste Utility-Assembly aktualisiert werden.

Anstatt von den verbrauchenden Projekten zu verlangen, einen neuen Verweis auf die Common-Assembly hinzuzufügen, können Sie den Typ weiterleiten. Da dieser Typ aus der Utility-Assembly entfernt wurde, müssen Sie den Utility.csproj-Verweis auf Common.csproj einfügen:

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

Das vorherige C#-Projekt verweist jetzt auf die neu erstellte allgemeine Assembly. Dies kann entweder eine PackageReference oder ProjectReference sein. Die Utility-Assembly muss die Typweiterleitungsinformationen bereitstellen. Je nach Konvention werden Typweiterleitungsdeklarationen normalerweise in einer einzelnen Datei mit dem Namen TypeForwardersgekapselt. Betrachten Sie die folgende C#-Datei TypeForwarders.cs in der Utility-Assembly:

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

[assembly:TypeForwardedTo(typeof(Example))]

Die Utility Assembly verweist auf die Common Assembly und leitet den Example Typ weiter. Wenn Sie die Utility-Assembly mit den Typweiterleitungsdeklarationen kompilieren und die Utility.dll-Datei in den Consuming-Bin ablegen, funktioniert die verarbeitende App ohne Kompilierung.

Siehe auch