다음을 통해 공유


공용 언어 런타임의 타입 전달

형식 전달을 사용하면 원래 어셈블리를 사용하는 애플리케이션을 다시 컴파일하지 않고도 형식을 다른 어셈블리로 이동할 수 있습니다.

예를 들어, 애플리케이션이 Example 클래스를 Utility.dll 어셈블리에서 사용한다고 가정합니다. Utility.dll 개발자는 어셈블리를 리팩터링하기로 결정할 수 있으며, 그 과정에서 클래스를 Example 다른 어셈블리로 이동할 수 있습니다. 이전 버전의 Utility.dll 새 버전의 Utility.dll 및 해당 도우미 어셈블리로 대체되는 경우 새 버전의 Example클래스를 찾을 Example 수 없으므로 클래스를 사용하는 애플리케이션이 실패합니다.

Utility.dll 개발자는 Example 특성을 사용하고 TypeForwardedToAttribute 클래스에 대한 요청을 전달하여 이를 방지할 수 있습니다. 특성이 새 버전의 Utility.dll적용된 경우 클래스에 대한 Example 요청은 이제 클래스가 포함된 어셈블리로 전달됩니다. 기존 애플리케이션은 다시 컴파일하지 않고 정상적으로 계속 작동합니다.

형식 전달

형식을 전달하는 네 가지 단계가 있습니다.

  1. 원래 어셈블리에서 대상 어셈블리로 형식의 소스 코드를 이동합니다.

  2. 이전 형식이 있던 어셈블리에서 이동된 형식에 대해 TypeForwardedToAttribute를 추가합니다. 다음 코드는 이동된 형식 Example 의 특성을 보여줍니다.

     [assembly:TypeForwardedToAttribute(Example::typeid)]
    
     [assembly:TypeForwardedToAttribute(typeof(Example))]
    
  3. 이제 형식이 포함된 어셈블리를 컴파일합니다.

  4. 현재 형식이 포함된 어셈블리에 대한 참조를 사용하여 형식이 있던 어셈블리를 다시 컴파일합니다. 예를 들어 명령줄에서 C# 파일을 컴파일하는 경우 참조 (C# 컴파일러 옵션) 옵션을 사용하여 형식이 포함된 어셈블리를 지정합니다. C++에서 소스 파일의 #using 지시문을 사용하여 형식이 포함된 어셈블리를 지정합니다.

C# 형식 전달 예제

위의 인위적인 예제 설명을 계속 진행하면서, 당신이 Utility.dll을 개발 중이고 클래스가 있다고 Example 상상해 보세요. Utility.csproj는 기본 클래스 라이브러리입니다.

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

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

</Project>

Example 클래스는 몇 가지 속성과 메서드 재정의를 제공합니다: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}";
}

이제 소비 프로젝트가 있고 소비자 어셈블리에 표현되었다고 상상해 보십시오. 이 사용 프로젝트는 유틸리티 어셈블리를 참조합니다. 예를 들어 개체를 Example 인스턴스화하고 Program.cs 파일의 콘솔에 씁니다.

using System;
using Common.Objects;

Example example = new();

Console.WriteLine(example);

사용 중인 앱이 실행되면 개체의 Example 상태가 출력됩니다. 이 시점에서 Consuming.csprojUtility.csproj를 참조하므로 형식 전달이 없습니다. 그러나 유틸리티 어셈블리의 개발자들은 리팩터링의 일환으로 Example 개체를 제거하기로 결정했습니다. 이 형식은 새로 만든 Common.csproj로 이동됩니다.

유틸리티 어셈블리에서 이 형식을 제거하면 개발자는 호환성이 손상되는 변경을 도입하고 있습니다. 사용 중인 모든 프로젝트는 최신 유틸리티 어셈블리로 업데이트할 때 중단됩니다.

사용 중인 프로젝트에서 Common 어셈블리에 새 참조를 추가하도록 요구하는 대신 형식을 전달할 수 있습니다. 유틸리티 어셈블리에서 이 형식이 제거되었으므로, Utility.csproj에서 Common.csproj를 참조해야 합니다.

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

이전 C# 프로젝트는 이제 새로 만든 Common 어셈블리를 참조합니다. 이는 PackageReference이거나 ProjectReference일 수 있습니다. 유틸리티 어셈블리는 형식 전달 정보를 제공해야 합니다. 규칙 유형에 따라 정방향 선언은 일반적으로 이름이 지정된 TypeForwarders단일 파일에 캡슐화됩니다. 유틸리티 어셈블리에서 다음 TypeForwarders.cs C# 파일을 고려합니다.

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

[assembly:TypeForwardedTo(typeof(Example))]

유틸리티 어셈블리는 Common 어셈블리를 참조하고 형식을 Example 전달합니다. 형식 전달 선언을 사용하여 유틸리티 어셈블리를 컴파일하고 Utility.dll소비 폴더에 넣으면, 소비하는 애플리케이션을 별도로 컴파일하지 않아도 작동합니다.

참고하십시오