A multi process runtime library based on 'SourceGenerator'.
基于 SourceGenerator
的多进程
运行库。
- 可以为
类型
、接口
、静态类
生成代理,无需手动编写RPC相关代码,即可多进程
运行; - 编译时生成所有代码,运行时无显式的反射调用和动态构造;
- 支持
委托
和CancellationToken
类型的方法参数(其余类型未特殊处理,将会进行序列化,目前回调委托
不支持嵌套和CancellationToken
); - 支持
Linux
、Windows
(其它未测试); - 支持调试子进程(
Windows
&&VisualStudio
Only); - AOT支持*(net8.0+);
- 目前参数不支持定义为父类型,实际传递子类型,序列化时将会按照定义的类型进行序列化和反序列化,会导致具体类型丢失;
- 目前所有的参数都不应该在方法完成后进行保留,
CancellationToken
、委托
等在方法完成后会被释放;
- .Net6.0+(其它版本没有尝试过)
<ItemGroup>
<PackageReference Include="Juxtapose" Version="1.4.0" />
<!--<PackageReference Include="Juxtapose.SourceGenerator" Version="1.0.0" /> 1.0.2 以后不再需要单独引用 SourceGenerator 包-->
</ItemGroup>
[Illusion(typeof(Greeter), "Juxtapose.Test.GreeterAsIGreeterIllusion")]
public partial class GreeterJuxtaposeContext : JuxtaposeContext
{
}
示例代码将为Greeter
生成代理类型Juxtapose.Test.GreeterAsIGreeterIllusion
;
Note!!!
- 必须继承
JuxtaposeContext
; - 必须标记
partial
关键字;
- 直接为类型生成代理,如下示例生成
Juxtapose.Test.GreeterIllusion
类型,且不继承接口(静态类型相同用法)
[Illusion(typeof(Greeter))]
为类型生成代理,并继承指定接口,如下示例生成Juxtapose.Test.GreeterAsIGreeterIllusion
类型且继承IGreeter
接口- 现在需要手动声明
partial
类来使生成的类型派生自目标接口
- 现在需要手动声明
partial class GreeterIllusion : IGreeter
{ }
- 生成类型,并指定类型名称,如下示例生成
Juxtapose.Test.HelloGreeter
类型
[Illusion(typeof(Greeter), generatedTypeName: "Juxtapose.Test.HelloGreeter")]
- 生成从IoC容器获取的接口代理类型,如下示例生成
Juxtapose.Test.IGreeterIllusionFromIoCContainer
类型(此时Context类需要实现IIoCContainerProvider
接口,并提供有效的IServiceProvider
)
[Illusion(typeof(IGreeterFromServiceProvider), generatedTypeName: "Juxtapose.Test.IGreeterIllusionFromIoCContainer", fromIoCContainer: true)]
在Main
方法开始处添加入口点代码,并使用指定上下文
await JuxtaposeEntryPoint.TryAsEndpointAsync(args, GreeterJuxtaposeContext.SharedInstance);
现在会自动附加调试器(启动项目需要直接引用Juxtapose
包,以确保依赖包正确引入)
- 声明 JsonSerializerContext
框架默认使用
System.Text.Json
进行消息的序列化与反序列化,需要手动定义JsonSerializerContext
声明所有类型:
[JsonSerializable(typeof(global::Juxtapose.Messages.JuxtaposeAckMessage))]
[JsonSerializable(typeof(global::Juxtapose.Messages.ExceptionMessage))]
[JsonSerializable(typeof(global::Juxtapose.Messages.InstanceMethodInvokeMessage<global::Juxtapose.Messages.ParameterPacks.CancellationTokenSourceCancelParameterPack>))]
[JsonSerializable(typeof(global::Juxtapose.Messages.DisposeObjectInstanceMessage))]
[JsonSerializable(typeof(global::Juxtapose.Messages.CreateObjectInstanceMessage<global::Juxtapose.Messages.ParameterPacks.ServiceProviderGetInstanceParameterPack>))]
// .........
[JsonSourceGenerationOptions(IgnoreReadOnlyProperties = false, IgnoreReadOnlyFields = false, IncludeFields = true, WriteIndented = false)]
partial class SampleJsonSerializerContext : JsonSerializerContext {}
- 重写
JuxtaposeContext
的CreateCommunicationMessageCodecFactory
方法 应用前置步骤声明的JsonSerializerContext
partial class SampleJuxtaposeContext : global::Juxtapose.JuxtaposeContext
{
protected override ICommunicationMessageCodecFactory CreateCommunicationMessageCodecFactory()
{
var communicationMessageCodec = new DefaultJsonBasedMessageCodec(GetMessageTypes(), LoggerFactory, SampleJsonSerializerContext.Default.Options);
return new GenericSharedMessageCodecFactory(communicationMessageCodec);
}
}
SourceGenerator
在编译时生成代理类型,封装通信消息。在创建代理类型对象时,会自动创建子进程,并在子进程中创建目标类型的对象,使用命名管道进行进程间通信,使用System.Text.Json
进行消息的序列化与反序列化。
关键字 | 名称 | 来源 | 作用 |
---|---|---|---|
Context | 上下文 | 手动定义 | 用于承载所有子进程运行的相关信息 |
Executor | 执行器 | 自动生成 | 用于运行时消息解析收发,创建对象,执行静态方法等 |
ParameterPack | 参数包 | 自动生成 | 将方法参数封装到一个类型中,以便序列化 |
Illusion | 幻象 | 自动生成 | 实际使用的类 |
RealObjectInvoker | 真实对象执行器 | 自动生成 | 在子进程中接收消息,并进行实际的对象方法调用 |
项目 | 内容 |
---|---|
SampleLibrary | 基于库的使用示例,可由其它程序直接使用 |
SampleConsoleApp | 基于控制台的使用示例,可使用当前程序集生成的类,或使用其他库生成的类 |
ResourceBasedObjectPool | 基于系统资源的动态对象池示例 |