Orleans generowanie kodu

Przed Orleans 7.0 generowanie źródła było znacznie bardziej ręczne i wymagało wyraźnej interwencji dewelopera. Orleans Począwszy od wersji 7.0, generowanie kodu jest automatyczne i nie wymaga interwencji dewelopera. Jednak nadal istnieją przypadki, w których deweloperzy mogą chcieć wpłynąć na generowanie kodu, na przykład w celu wygenerowania kodu dla typów, które nie są generowane automatycznie lub generowania kodu dla typów w innym zestawie.

Włączanie generowania kodu

Orleans generuje kod źródłowy języka C# dla aplikacji w czasie kompilacji. Wszystkie projekty, w tym host, muszą mieć zainstalowane odpowiednie pakiety NuGet, aby umożliwić generowanie kodu. Dostępne są następujące pakiety:

Użyj elementu , GenerateSerializerAttribute aby określić, że typ ma być serializowany, a kod serializacji powinien zostać wygenerowany dla typu. Aby uzyskać więcej informacji, zobacz Używanie Orleans serializacji.

Środowisko Orleans uruchomieniowe korzysta z wygenerowanego kodu w celu zapewnienia prawidłowej serializacji typów używanych w klastrze, a także do generowania standardowych elementów, które wyodrębniają szczegóły implementacji wysyłania metod, propagacji wyjątków i innych wewnętrznych pojęć dotyczących środowiska uruchomieniowego. Generowanie kodu można wykonać podczas kompilowania projektów lub inicjowania aplikacji.

Co się dzieje podczas kompilacji?

W czasie Orleans kompilacji generuje kod dla wszystkich typów oznaczonych jako GenerateSerializerAttribute. Jeśli typ nie jest oznaczony znakiem GenerateSerializer, nie będzie serializowany przez Orleanselement .

Jeśli programujesz przy użyciu języka F# lub Visual Basic, możesz również użyć generowania kodu. Aby uzyskać więcej informacji, zobacz następujące przykłady:

W tych przykładach pokazano, jak używać Orleans.GenerateCodeForDeclaringAssemblyAttributeelementu , określając typy w zestawie, dla których generator źródłowy powinien sprawdzać i generować źródło.

Preferowaną metodą wykonywania generowania kodu jest w czasie kompilacji. Generowanie kodu czasu kompilacji można włączyć przy użyciu jednego z następujących pakietów:

  • Microsoft.Orleans.OrleansCodeGenerator.Build. Pakiet, który używa narzędzia Roslyn do generowania kodu i używa Emocje.NET do analizy.
  • Microsoft.Orleans. CodeGenerator.MSBuild. Nowy pakiet generowania kodu, który korzysta z narzędzia Roslyn zarówno do generowania kodu, jak i analizy kodu. Nie ładuje plików binarnych aplikacji, a w związku z tym pozwala uniknąć problemów spowodowanych starciem wersji zależności i różnymi platformami docelowymi. Nowy generator kodu zwiększa również obsługę kompilacji przyrostowych, co powinno spowodować skrócenie czasu kompilacji.

Jeden z tych pakietów należy zainstalować we wszystkich projektach zawierających ziarna, interfejsy ziarna, niestandardowe serializatory lub typy wysyłane między ziarnami. Zainstalowanie pakietu powoduje wstrzyknięcie elementu docelowego do projektu, który wygeneruje kod w czasie kompilacji.

Oba pakiety (Microsoft.Orleans.CodeGenerator.MSBuild i Microsoft.Orleans.OrleansCodeGenerator.Build) obsługują tylko projekty języka C#. Inne języki są obsługiwane przy użyciu pakietu opisanego Microsoft.Orleans.OrleansCodeGenerator poniżej lub przez utworzenie projektu języka C#, który może działać jako element docelowy kodu wygenerowanego na podstawie zestawów napisanych w innych językach.

Dodatkową diagnostykę można emitować w czasie kompilacji, określając wartość parametru OrleansCodeGenLogLevel w pliku csproj projektu docelowego. Na przykład <OrleansCodeGenLogLevel>Trace</OrleansCodeGenLogLevel>.

Co się stanie podczas inicjowania?

W Orleans wersji 7+ podczas inicjowania nic się nie dzieje. Generowanie kodu jest wykonywane w czasie kompilacji.

Generowanie kodu można wykonać podczas inicjowania na kliencie i silosie, instalując Microsoft.Orleans.OrleansCodeGenerator pakiet i używając ApplicationPartManagerCodeGenExtensions.WithCodeGeneration metody rozszerzenia:

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

W tym przykładzie builder może być wystąpieniem elementu ISiloHostBuilder lub IClientBuilder. Opcjonalne ILoggerFactory wystąpienie można przekazać w celu WithCodeGeneration włączenia rejestrowania podczas generowania kodu, na przykład:

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

Wpływ na generowanie kodu

Podczas stosowania GenerateSerializerAttribute do typu można również zastosować element IdAttribute , aby jednoznacznie zidentyfikować element członkowski. Podobnie możesz również zastosować alias za pomocą elementu AliasAttribute. Aby uzyskać więcej informacji na temat wpływu na generowanie kodu, zobacz Używanie Orleans serializacji.

Podczas generowania kodu można wpływać na generowanie kodu dla określonego typu. Kod jest generowany automatycznie dla interfejsów ziarna, klas ziarna, stanu ziarna i typów przekazywanych jako argumenty w metodach ziarna. Jeśli typ nie pasuje do tych kryteriów, następujące metody mogą służyć do dalszego generowania kodu.

Dodanie SerializableAttribute do typu powoduje, że generator kodu wygeneruje serializator dla tego typu.

Dodanie [assembly: GenerateSerializer(Type)] do projektu powoduje, że generator kodu traktuje ten typ jako serializowalny i spowoduje błąd, jeśli nie można wygenerować serializatora dla tego typu, na przykład, ponieważ typ nie jest dostępny. Ten błąd spowoduje zatrzymanie kompilacji w przypadku włączenia generowania kodu. Ten atrybut umożliwia również generowanie kodu dla określonych typów z innego zestawu.

[assembly: KnownType(Type)] Instruuje również generator kodu, aby zawierał określony typ (który może pochodzić z zestawu, do którego odwołuje się odwołanie), ale nie powoduje wyjątku, jeśli typ jest niedostępny.

Generowanie serializatorów dla wszystkich podtypów

Dodanie KnownBaseTypeAttribute do interfejsu lub klasy powoduje, że generator kodu generuje kod serializacji dla wszystkich typów, które dziedziczą/implementują ten typ.

Generowanie kodu dla wszystkich typów w innym zestawie

Istnieją przypadki, w których wygenerowany kod nie może być uwzględniony w określonym zestawie w czasie kompilacji. Na przykład może to obejmować biblioteki udostępnione, które nie odwołują się do Orleanszestawów napisanych w językach innych niż C#, oraz zestawów, w których deweloper nie ma kodu źródłowego. W takich przypadkach wygenerowany kod dla tych zestawów można umieścić w oddzielnym zestawie, do którego odwołuje się podczas inicjowania.

Aby włączyć to dla zestawu:

  1. Utwórz projekt w języku C#.
  2. Microsoft.Orleans.CodeGenerator.MSBuild Zainstaluj pakiet lub Microsoft.Orleans.OrleansCodeGenerator.Build .
  3. Dodaj odwołanie do zestawu docelowego.
  4. Dodaj [assembly: KnownAssembly("OtherAssembly")] na najwyższym poziomie pliku C#.

Polecenie KnownAssemblyAttribute instruuje generator kodu, aby sprawdzić określony zestaw i wygenerować kod dla typów w nim. Atrybut może być używany wiele razy w projekcie.

Wygenerowany zestaw należy następnie dodać do klienta/silosu podczas inicjowania:

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

W tym przykładzie builder może być wystąpieniem elementu ISiloHostBuilder lub IClientBuilder.

KnownAssemblyAttribute ma opcjonalną właściwość , TreatTypesAsSerializablektórą można ustawić, aby true poinstruować generator kodu, aby działał tak, jakby wszystkie typy w tym zestawie były oznaczone jako serializowalne.