Orleans 코드 생성

Orleans 7.0 이전에는 원본 생성이 훨씬 더 수동적이었으며 명시적 개발자 개입이 필요했습니다. Orleans 7.0부터 코드 생성은 자동이며 개발자 개입이 필요하지 않습니다. 그러나 개발자가 자동으로 생성되지 않는 형식에 대한 코드를 생성하거나 다른 어셈블리의 형식에 대한 코드를 생성하기 위해 코드 생성에 영향을 주려는 경우가 여전히 있습니다.

소스 생성 사용 설정

Orleans는 빌드 시 앱에 대한 C# 소스 코드를 생성합니다. 호스트를 포함한 모든 프로젝트에는 코드를 생성할 수 있도록 적절한 NuGet 패키지가 설치되어 있어야 합니다. 다음 패키지를 사용할 수 있습니다.

GenerateSerializerAttribute를 사용하여 형식을 직렬화하도록 지정하고 해당 형식에 대해 직렬화 코드를 생성하도록 지정합니다. 자세한 내용은 Orleans 직렬화 사용을 참조하세요.

Orleans 런타임은 생성된 코드를 사용하여 클러스터 전체에서 사용되는 형식의 적절한 직렬화를 보장하고 상용구를 생성하여 메서드 전달, 예외 전파, 기타 내부 런타임 개념의 구현 세부 정보를 추상화합니다. 프로젝트를 빌드할 때 또는 애플리케이션이 초기화될 때 코드 생성을 수행할 수 있습니다.

빌드 중에는 어떤 일이 발생하나요?

빌드 시 Orleans는 GenerateSerializerAttribute로 표시된 모든 형식에 대한 코드를 생성합니다. 형식이 GenerateSerializer로 표시되어 있지 않으면 Orleans로 직렬화되지 않습니다.

F# 또는 Visual Basic을 사용하여 개발하는 경우 코드 생성을 사용할 수도 있습니다. 자세한 내용은 다음 샘플을 참조하세요.

다음 예제에서는 원본 생성기에서 원본을 검사하고 생성해야 하는 어셈블리의 형식을 지정하는 Orleans.GenerateCodeForDeclaringAssemblyAttribute 사용 방법을 보여 줍니다.

코드 생성을 수행하기 위한 선호하는 방법은 빌드 시간입니다. 다음 패키지 중 하나를 사용하여 빌드 시간 코드 생성을 사용하도록 설정할 수 있습니다.

  • Microsoft.Orleans.OrleansCodeGenerator.Build. 코드 생성에 Roslyn을 사용하고 분석에 .NET 리플렉션을 사용하는 패키지입니다.
  • Microsoft.Orleans.CodeGenerator.MSBuild. 코드 생성 및 코드 분석 모두에 Roslyn을 활용하는 새 코드 생성 패키지입니다. 애플리케이션 이진 파일을 로드하지 않으므로 종속성 버전 충돌 및 다른 대상 프레임워크로 인한 문제를 방지합니다. 또한 새 코드 생성기는 증분 빌드에 대한 지원을 개선하므로 빌드 시간이 단축됩니다.

이러한 패키지 중 하나는 조직, 조직 인터페이스, 사용자 지정 직렬 변환기 또는 조직 간에 전송된 형식을 포함하는 모든 프로젝트에 설치해야 합니다. 패키지를 설치하면 빌드 시 코드를 생성할 프로젝트에 대상이 삽입됩니다.

두 패키지(Microsoft.Orleans.CodeGenerator.MSBuildMicrosoft.Orleans.OrleansCodeGenerator.Build)만 C# 프로젝트를 지원합니다. 다른 언어는 아래에 설명된 Microsoft.Orleans.OrleansCodeGenerator 패키지를 사용하여 지원되거나 다른 언어로 작성된 어셈블리에서 생성된 코드의 대상으로 사용할 수 있는 C# 프로젝트를 만들어 지원됩니다.

대상 프로젝트의 .csproj 파일에 OrleansCodeGenLogLevel 값을 지정하여 빌드 시 추가 진단을 내보낼 수 있습니다. 예들 들어 <OrleansCodeGenLogLevel>Trace</OrleansCodeGenLogLevel>입니다.

초기화 중에는 어떤 일이 발생하나요?

Orleans 7 이상에서는 초기화 중에 아무 일도 발생하지 않습니다. 코드 생성은 빌드 시 수행됩니다.

코드 생성은 Microsoft.Orleans.OrleansCodeGenerator 패키지를 설치하고 ApplicationPartManagerCodeGenExtensions.WithCodeGeneration 확장 방법을 사용하여 클라이언트 및 사일로에서 초기화하는 동안 수행할 수 있습니다.

builder.ConfigureApplicationParts(
    parts => parts
        .AddApplicationPart(typeof(IRuntimeCodeGenGrain).Assembly)
        .WithCodeGeneration());

앞에서 설명한 예제에서 builderISiloHostBuilder 또는 IClientBuilder의 인스턴스일 수 있습니다. 예를 들어, 코드 생성 중에 로깅을 사용하도록 설정하기 위해 선택적 ILoggerFactory 인스턴스를 WithCodeGeneration에 전달할 수 있습니다.

ILoggerFactory codeGenLoggerFactory = new LoggerFactory();
codeGenLoggerFactory.AddProvider(new ConsoleLoggerProvider());
    builder.ConfigureApplicationParts(
        parts => parts
            .AddApplicationPart(typeof(IRuntimeCodeGenGrain).Assembly)
            .WithCodeGeneration(codeGenLoggerFactory));

코드 생성에 영향

형식에 GenerateSerializerAttribute를 적용할 때 IdAttribute를 적용하여 멤버를 고유하게 식별할 수도 있습니다. 마찬가지로 AliasAttribute를 사용하여 별칭을 적용할 수도 있습니다. 코드 생성에 영향을 주는 방법에 대한 자세한 내용은 Orleans 직렬화 사용을 참조하세요.

코드를 생성하는 동안 특정 형식에 대한 코드 생성에 영향을 줄 수 있습니다. 조직 인터페이스, 조직 클래스, 조직 상태 및 조직 메서드의 인수로 전달되는 형식에 대한 코드가 자동으로 생성됩니다. 형식이 이러한 조건에 맞지 않는 경우 다음 메서드를 사용하여 코드 생성을 추가로 안내할 수 있습니다.

형식에 SerializableAttribute를 추가하여 코드 생성기에 해당 형식에 대한 직렬 변환기를 생성하도록 지시합니다.

프로젝트에 [assembly: GenerateSerializer(Type)]를 추가하여 코드 생성기가 해당 형식을 직렬화 가능으로 처리하도록 지시하고, 해당 형식에 대해 직렬 변환기를 생성할 수 없는 경우(예를 들어 형식에 액세스할 수 없기 때문에)에는 오류가 발생합니다. 이 오류는 코드 생성이 사용 설정된 경우 빌드를 중지합니다. 이 특성을 사용하면 다른 어셈블리에서 특정 형식에 대한 코드를 생성할 수도 있습니다.

[assembly: KnownType(Type)] 역시 코드 생성기에 특정 형식(참조된 어셈블리의 형식일 수 있음)을 포함하도록 지시하지만 형식에 액세스할 수 없는 경우에는 예외가 발생하지 않습니다.

모든 하위 형식에 대한 직렬 변환기 생성

인터페이스 또는 클래스에 KnownBaseTypeAttribute를 추가하여 코드 생성기에 해당 형식을 상속/구현하는 모든 형식에 대한 serialization 코드를 생성하도록 지시합니다.

다른 어셈블리의 모든 형식에 대한 코드 생성

생성된 코드를 빌드 시 특정 어셈블리에 포함할 수 없는 경우가 있습니다. 예를 들어 Orleans를 참조하지 않는 공유 라이브러리, C#이 아닌 언어로 작성된 어셈블리, 개발자에게 소스 코드가 없는 어셈블리가 포함될 수 있습니다. 이러한 경우 해당 어셈블리에 대해 생성된 코드를 초기화 중에 참조되는 별도의 어셈블리에 배치할 수 있습니다.

어셈블리에 사용하도록 설정하려면 다음을 수행합니다.

  1. C# 프로젝트를 만듭니다.
  2. Microsoft.Orleans.CodeGenerator.MSBuild 또는 Microsoft.Orleans.OrleansCodeGenerator.Build 패키지를 설치합니다.
  3. 대상 어셈블리에 대한 참조를 추가합니다.
  4. C# 파일의 최상위 수준에 [assembly: KnownAssembly("OtherAssembly")]를 추가합니다.

KnownAssemblyAttribute는 코드 생성기에 지정된 어셈블리를 검사하고 해당 어셈블리 내의 형식에 대한 코드를 생성하도록 지시합니다. 이 특성은 프로젝트 내에서 여러 번 사용할 수 있습니다.

그런 다음, 초기화 중에 생성된 어셈블리를 클라이언트/사일로에 추가해야 합니다.

builder.ConfigureApplicationParts(
    parts => parts.AddApplicationPart("CodeGenAssembly"));

앞에서 설명한 예제에서 builderISiloHostBuilder 또는 IClientBuilder의 인스턴스일 수 있습니다.

KnownAssemblyAttribute에는 선택적 속성인 TreatTypesAsSerializable이 있으며 이 속성을 true로 설정하여 코드 생성기에 해당 어셈블리 내의 모든 형식이 직렬화 가능으로 표시된 것처럼 작동하도록 지시할 수 있습니다.