Orleans TestClusterBuilder无法共享依赖注入注册的问题求助
解决Orleans测试集群与Web应用测试服务注册重复、实例不一致问题
问题核心
你在单元测试中同时构建了Web应用容器和Orleans TestCluster,两者各自注册了Something单例服务,导致Web应用和Grains拿到的是两个独立的实例,同时出现重复注册问题。本质原因是Web应用的ServiceProvider与Orleans Silo的ServiceProvider是完全独立的容器,各自维护自己的服务实例。
解决方案
核心思路是复用Web应用中已注册的单例实例,让Orleans Silo直接使用这个实例,而非重新注册。
步骤1:抽离公共服务注册逻辑(可选但推荐)
避免重复编写注册代码,把公共服务注册抽成可复用的方法:
public static class CommonServiceRegistrations { // 针对Autofac ContainerBuilder的注册方法 public static void RegisterSharedServices(ContainerBuilder builder) { builder.RegisterType<Something>().AsSelf().SingleInstance(); // 其他需要共享的服务注册都放在这里 } }
在Web应用的Setup中调用该方法:
webApplicationBuilder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureContainer<ContainerBuilder>(c => { CommonServiceRegistrations.RegisterSharedServices(c); });
步骤2:让Orleans Silo复用Web应用的单例实例
Web应用构建完成后,从其ServiceProvider中获取已创建的Something实例,再将该实例直接注册到Orleans Silo的服务配置中:
[SetUp] public void Setup() { var webApplicationBuilder = WebApplication.CreateBuilder(); webApplicationBuilder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureContainer<ContainerBuilder>(c => { CommonServiceRegistrations.RegisterSharedServices(c); }); var app = webApplicationBuilder.Build(); // 获取Web应用中已注册的单例实例 var sharedSomething = app.Services.GetRequiredService<Something>(); var testClusterBuilder = new TestClusterBuilder(1); // 直接配置Silo的服务,传入已有的单例实例 testClusterBuilder.ConfigureSilo(siloBuilder => { siloBuilder.ConfigureServices(services => { // 注册已存在的实例,而非重新创建 services.AddSingleton<Something>(sharedSomething); }); }); TestCluster = testClusterBuilder.Build(); TestCluster.Deploy(); }
原理说明
通过这种方式,Orleans Silo的服务容器会直接使用Web应用中已经初始化好的Something单例实例,既避免了重复注册,又保证了Web应用和Grains拿到的是同一个实例,解决了实例不一致的问题。
内容的提问来源于stack exchange,提问作者Alex Dresko
相关产品推荐
相关产品推荐

