访问Azure Service Fabric状态服务状态

我已将WebAPI添加到我的有状态服务器中,并希望从中访问StateManager (来自StatefulService类实现之外)。

最好的方法是什么?

目前我正在使用一个小类:

 internal static class InstanceAccessor { internal static StatefulService ActiveInstance { get; set; } } 

并将值放在StatefulService RunAsync方法中:

 protected override async Task RunAsync(CancellationToken cancellationToken) { InstanceAccessor.ActiveInstance = this; ... 

在Github上有一个示例项目,它显示了使用dependency injection的简单方法。

您的服务可能会有多个并发调用访问共享实例,在您的代码中,可能(但稍微不太可能)在RunAsync设置实例之前执行对WebApi的请求。 您可以将分配移动到服务的.ctor。 但是,由于它只是读取您将对共享实例执行的操作,因此在设置实例后无需担心冲突。

该解决方案的问题是可测试性。 如果要为WebAPi编写unit testing,它将对共享实例具有依赖性。 有关此内容的更多信息,请参阅此答案: 使用单例进行unit testing

另一种可能对您有用的方法是使用dependency injection和IoC容器。 您可以将WebApi控制器设置为由引用所有依赖项(包括您的服务)的容器构造。 为Service Fabric / WebApi设置IoC和dependency injection可以按照https://stackoverflow.com/a/41980513/1062217所述进行 。 您只需要在控制器.ctor添加对StatefulService的依赖。

  public SomeApiController(StatefulService service) { _service = service; } 

并在容器中注册服务

 public WebApiService(StatefulServiceContext context) : base(context) { Container = new TinyIoCContainer(); Container.Register(this); } 

但是,如果它只是WebApi控制器中需要的Statemanager,那么如果您只依赖于StateManager ,您的实现将更容易测试和维护:

  public SomeApiController(IReliableStateManagerReplica stateManager) { _stateManager = stateManager; } 

并在服务中注册.ctor:

 public WebApiService(StatefulServiceContext context) : base(context) { Container = new TinyIoCContainer(); Container.Register(this.StateManager); } 

请注意,此示例使用TinyIoC,但任何IoC容器都可以使用