You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure有状态服务:.NET Core中用远程处理注册自定义单例类

在.NET Core有状态服务中使用远程处理并注册自定义单例的可行性方案

当然可行!不过你遇到的ConfigureServices()没被调用的情况是正常的——因为当你使用CreateServiceRemotingReplicaListeners()启用服务远程处理,并且移除了Kestrel配置后,ASP.NET Core的托管管道并没有被启动,所以Startup类里的配置方法自然不会执行。下面给你两种靠谱的解决方案:

方法一:直接在服务构造函数中初始化单例

这种方式最简单,适合单例没有复杂依赖的场景。因为有状态服务的每个副本只会被实例化一次,所以在构造函数里初始化的对象天然就是副本内的单例:

public class MyStatefulService : StatefulService
{
    // 声明单例实例
    private readonly MyCustomSingleton _customSingleton;

    public MyStatefulService(StatefulServiceContext context)
        : base(context)
    {
        // 初始化单例,确保每个服务副本只创建一次
        _customSingleton = new MyCustomSingleton();
        // 如果单例需要其他依赖,也可以在这里手动注入
    }

    protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
    {
        // 返回远程处理监听器
        yield return new ServiceReplicaListener(context =>
            new FabricTransportServiceRemotingListener(context, this));
    }

    // 远程调用方法中直接使用单例
    public async Task ExecuteSingletonLogic()
    {
        await _customSingleton.DoWorkAsync();
    }
}

方法二:使用自定义依赖注入容器管理单例

如果你的单例有复杂的依赖链,或者想更规范地管理依赖,可以手动构建一个DI容器,在服务启动时注册单例:

public class MyStatefulService : StatefulService
{
    private readonly IServiceProvider _serviceProvider;

    public MyStatefulService(StatefulServiceContext context)
        : base(context)
    {
        var services = new ServiceCollection();
        
        // 注册自定义单例
        services.AddSingleton<MyCustomSingleton>();
        // 注册单例依赖的其他服务
        services.AddSingleton<IDependencyService, DependencyServiceImpl>();
        
        // 构建服务提供者
        _serviceProvider = services.BuildServiceProvider();
    }

    protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
    {
        yield return new ServiceReplicaListener(context =>
            new FabricTransportServiceRemotingListener(context, this));
    }

    public async Task ExecuteSingletonLogic()
    {
        // 从容器中获取单例实例
        var singleton = _serviceProvider.GetRequiredService<MyCustomSingleton>();
        await singleton.DoWorkAsync();
    }
}

重要注意事项

  • 这里的单例是服务副本内的单例:因为Service Fabric的有状态服务每个副本都是独立的进程/实例,内存不共享。如果需要跨副本的全局单例,你得借助可靠状态管理器存储状态,或者使用外部分布式缓存来实现。
  • 避免在单例中存储副本特有的状态:如果单例需要访问有状态服务的可靠状态管理器,建议在调用时传入,或者让单例依赖StatefulServiceContext来获取状态管理器。

内容的提问来源于stack exchange,提问作者Luca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:24:35