Compartilhar via


Geração de código no Orleans

Antes da versão Orleans 7.0, a geração de código era mais manual e exigia a intervenção explícita do desenvolvedor. Orleans A partir da 7.0, a geração de código é automática e normalmente não requer nenhuma intervenção. No entanto, ainda existem casos em que influenciar a geração de código pode ser desejável, por exemplo, para gerar código para tipos não gerados automaticamente ou para tipos em outro assembly.

Habilitar geração de código

Orleans gera o código-fonte C# para o aplicativo no momento da compilação. Todos os projetos, incluindo o host, precisam dos pacotes NuGet apropriados instalados para habilitar a geração de código. Os seguintes pacotes estão disponíveis:

Use o GenerateSerializerAttribute para especificar que o tipo se destina à serialização e que Orleans deve gerar código de serialização para ele. Para obter mais informações, confira Usar serialização doOrleans.

O Orleans runtime usa o código gerado para garantir a serialização adequada dos tipos usados no cluster e gerar código clichê. Este código padrão abstrai os detalhes de implementação do despacho de métodos, propagação de exceções e outros conceitos internos de tempo de execução. A geração de código pode ser executada ao criar projetos ou quando o aplicativo é inicializado.

Geração de código em tempo de compilação

No momento do build, Orleans gera código para todos os tipos marcados com GenerateSerializerAttribute. Se um tipo não estiver marcado com GenerateSerializer, Orleans não o serializará.

Se estiver desenvolvendo com F# ou Visual Basic, a geração de código também poderá ser usada. Para obter mais informações, confira estes exemplos:

Esses exemplos demonstram o uso do Orleans.GenerateCodeForDeclaringAssemblyAttribute, especificando tipos no assembly para o gerador de código fonte inspecionar e gerar código-fonte.

O método preferido para geração de código é durante o tempo de compilação. Habilite a geração de código em tempo de build usando um dos seguintes pacotes:

  • Microsoft.Orleans.OrleansCodeGenerator.Build: um pacote que usa Roslyn para geração de código e reflexão do .NET para análise.
  • Microsoft.Orleans.CodeGenerator.MSBuild: um pacote de geração de código mais recente aproveitando Roslyn para geração e análise de código. Ele não carrega binários de aplicativo, evitando problemas causados por versões de dependência conflitantes e estruturas de destino diferentes. Esse gerador de código também melhora o suporte para builds incrementais, resultando em tempos de build mais curtos.

Instale um desses pacotes em todos os projetos que contêm grãos, interfaces de grãos, serializadores personalizados ou tipos enviados entre grãos. A instalação de um pacote injeta um destino no projeto que gera código no momento da compilação.

Ambos os pacotes (Microsoft.Orleans.CodeGenerator.MSBuild e Microsoft.Orleans.OrleansCodeGenerator.Build) dão suporte apenas a projetos C#. Dê suporte a outros idiomas usando o Microsoft.Orleans.OrleansCodeGenerator pacote (descrito abaixo) ou criando um projeto C# atuando como o destino do código gerado a partir de assemblies escritos em outros idiomas.

Emita diagnósticos adicionais no momento do build ao especificar um valor para OrleansCodeGenLogLevel no arquivo .csproj do projeto de destino. Por exemplo: <OrleansCodeGenLogLevel>Trace</OrleansCodeGenLogLevel>.

Geração de código no momento da inicialização

Em Orleans 7+, nada acontece durante a inicialização. A geração de código ocorre somente no momento da compilação.

A geração de código pode ser realizada durante a inicialização no cliente e no silo instalando o Microsoft.Orleans.OrleansCodeGenerator pacote e usando o ApplicationPartManagerCodeGenExtensions.WithCodeGeneration método de extensão:

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

No exemplo anterior, builder pode ser uma instância de um ISiloHostBuilder ou IClientBuilder. Passe uma instância opcional ILoggerFactory para WithCodeGeneration para habilitar o registro em log durante a geração de código, por exemplo:

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

Influenciar a geração de código

Ao aplicar GenerateSerializerAttribute a um tipo, também IdAttribute pode ser aplicado para identificar exclusivamente o membro. Da mesma forma, um alias pode ser aplicado usando o AliasAttribute. Para obter mais informações sobre como influenciar a geração de código, consulte Usar Orleans serialização.

Durante a geração de código, a geração de código para um tipo específico pode ser influenciada. Orleans gera automaticamente código para interfaces de grãos, classes de grãos, estado de grãos e tipos passados como argumentos em métodos de grãos. Se um tipo não se ajustar a esses critérios, use os métodos a seguir para orientar ainda mais a geração de código.

Adicionar SerializableAttribute a um tipo instrui o gerador de código a gerar um serializador para ele.

Adicionar [assembly: GenerateSerializer(Type)] a um projeto instrui o gerador de código a tratar esse tipo como serializável. Isso causará um erro se um serializador não puder ser gerado para esse tipo (por exemplo, porque o tipo não está acessível). Esse erro interromperá o build se a geração de código estiver habilitada. Este atributo também permite gerar código para tipos específicos de outro assembly.

[assembly: KnownType(Type)] também instrui o gerador de código a incluir um tipo específico (que pode ser de um assembly referenciado), mas não causará uma exceção se o tipo estiver inacessível.

Gerar serializadores para todos os subtipos

Adicionar KnownBaseTypeAttribute a uma interface ou classe instrui o gerador de código a gerar código de serialização para todos os tipos que herdam ou implementam esse tipo.

Gerar código para todos os tipos em outro assembly

Às vezes, o código gerado não pode ser incluído em um assembly específico no momento da compilação. Os exemplos incluem bibliotecas compartilhadas que não fazem referência Orleans, assemblies escritos em idiomas diferentes de C#e assemblies para os quais o código-fonte não está disponível. Nesses casos, coloque o código gerado para esses assemblies em um assembly separado que seja referenciado durante a inicialização.

Para habilitar isso para um assembly:

  1. Criar um Projeto C#
  2. Instale o pacote Microsoft.Orleans.CodeGenerator.MSBuild ou Microsoft.Orleans.OrleansCodeGenerator.Build.
  3. Adicione uma referência ao assembly de destino.
  4. Adicione [assembly: KnownAssembly("OtherAssembly")] no nível superior de um arquivo C#.

O KnownAssemblyAttribute instrui o gerador de código a inspecionar o assembly especificado e gerar código para os tipos dentro dele. Esse atributo pode ser usado várias vezes em um projeto.

Em seguida, adicione o assembly gerado ao cliente/silo durante a inicialização:

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

No exemplo anterior, builder pode ser uma instância de um ISiloHostBuilder ou IClientBuilder.

KnownAssemblyAttributetem uma propriedade opcional. TreatTypesAsSerializable Defina isso para true para instruir o gerador de código a agir como se todos os tipos dentro desse assembly estivessem marcados como serializáveis.