Orleans 2.0 官方文档 —— 3.3 核心概念 -> 代码生成

代码生成

Orleans运行时使用生成的代码,以确保跨集群时使用的类型的正确序列化,以及生成样板文件,该样板文件抽象出方法传送、异常传播和其他内部的运行时概念的实现细节。

启用代码生成

既可以在项目被build时,也可以在应用程序初始化时,执行代码生成。

在build期间

执行代码生成的首选方法是在build时。可以使用以下包之一,启用build时代码生成:

  • Microsoft.Orleans.OrleansCodeGenerator.Build。使用Roslyn进行代码生成,并使用.NET Reflection进行分析的包。
  • Microsoft.Orleans.CodeGenerator.MSBuild。一个新的代码生成包,它利用Roslyn进行代码生成和代码分析。它不加载应用程序的二进制文件,因此避免了因冲突的依赖项版本和不同的目标框架而导致的问题。新的代码生成器还改进了对增量构建的支持,这会缩短build时间。

    这些包中的之一,应该被安装到全部的项目,这些项目包含grain,grain 接口,自定义序列化器,或那些在grain之间被发送的类型。安装一个包,会将一个目标注入到项目,该项目将在build时生成代码。

两个包(Microsoft.Orleans.CodeGenerator.MSBuildMicrosoft.Orleans.OrleansCodeGenerator.Build)仅支持C#项目。其他语言可以使用下面描述的Microsoft.Orleans.OrleansCodeGenerator包来获得支持,也可以创建一个C#项目,该项目的代码,可以从其他语言编写的程序集中生成。

通过在目标项目的csproj文件中,指定OrleansCodeGenLogLevel的值,可以在build时报出附加的诊断信息。例如,Trace

初始化期间

通过安装Microsoft.Orleans.OrleansCodeGenerator包,并使用IApplicationPartManager.WithCodeGeneration扩展方法,可以在client和silo上的初始化期间,执行代码生成。

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

在上面的例子中,builder可以是ISiloHostBuilderIClientBuilder的一个实例。可选的ILoggerFactory实例,可以被传给WithCodeGeneration,以在代码生成期间启用日志记录,例如:

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

影响代码生成

生成某指定类型的代码

grain接口,grain类,grain状态以及在grain的方法中作为参数传递的类型,会自动生成代码。如果某类型不符合此条件,则可以使用以下方法,来进一步引导代码生成。

添加[Serializable]到某个类型,会指示代码生成器为该类型生成序列化器。

添加[assembly: GenerateSerializer(Type)]到某个项目,会指示代码生成器将该类型视为可序列化,如果无法为该类型生成序列化器(例如因为该类型不可访问),则会导致错误。如果启用了代码生成,则此错误将停止build。此属性还允许从另一个程序集生成指定类型的代码。

[assembly: KnownType(Type)] 还指示代码生成器,包含某指定的类型(可能来自引用的程序集),但如果类型不可访问,则不会导致异常。

为所有子类型生成序列化器

添加[KnownBaseType]到接口或类,则指示代码生成器,为继承/实现该类型的所有类型,生成序列化代码。

为另一个程序集中的所有类型生成代码

在有些情况下,生成的代码在build时,不能包含在特定的程序集中。例如,这可以包括不引用Orleans的共享库,用C#以外的语言编写的程序集,以及开发人员没有源代码的程序集。在这些情况下,可以将为这些程序集生成的代码放入一个单独的程序集中,该程序集在初始化期间被引用。

要为某个程序集启用这一功能,请执行以下操作:

  1. 创建一个C#项目。
  2. 安装Microsoft.Orleans.CodeGenerator.MSBuildMicrosoft.Orleans.OrleansCodeGenerator.Build包。
  3. 添加对目标程序集的引用。
  4. 在C#文件的顶部,添加[assembly: KnownAssembly("OtherAssembly")]

KnownAssembly属性指示代码生成器,检查指定的程序集,并为其中的类型生成代码。该属性可以在项目中多次使用。

然后,必须在初始化期间,将生成的程序集,添加到client/silo:

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

在上面的例子中,builder可以是ISiloHostBuilderIClientBuilder的一个实例。

KnownAssemblyAttribute有一个可选属性,TreatTypesAsSerializable,可以将其设置为true,来指示代码生成器,就好像该程序集中的所有类型都标记为可序列化一样。

你可能感兴趣的:(Orleans)