访问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容器都可以使用