WebAPI控制器访问其无状态服务实例



我在一个实例的无状态服务中托管WebAPI控制器。服务实例(我的意思是由SF运行时创建的WebApiservice类的实例)将某些瞬态状态保持为成员字段,并通过内部(线程安全)方法公开状态。WebAPI控制器需要调用访问该状态的方法。

WebApiService.cs:
-----------------
internal sealed class WebApiService : StatelessService
{
  private int _state;
  internal int GetState() { return this._state; }
ServiceController.cs:
---------------------
public class ServiceController : ApiController
{
  public async Task<IHttpActionResult> GetStateAsync()
  {
    // Here I'd like to grab somehow the WebApiService instance 
    // and call its GetState internal method.

我的问题是:

  1. 控制器如何获得对WebApiservice实例的引用?

  2. 在静态字段中存储WebApiservice实例是否安全(也许在Webaspiservice构造函数中设置)?

通过DI容器注入服务实例作为对您的控制器的依赖。

这是使用Unity在Katana上托管的Web API的示例。这是一项状态服务,但对于无国籍服务的工作方式完全相同:https://github.com/azure-samples/service-fabric-dotnet-getting-started/tree/tree/master/master/services/wordcount/wordcount/wordcount/wordcount/wordcount.service

这是使用ASP.NET Core及其内置依赖性注入容器(也适用但适用同样的东西)的示例:/xray.data

我认为您可以使用DI容器。我可以推荐简单注射器(但是有很多可以做同样的功能),SimpleInjector也可以根据请求和Web API软件包具有对象寿命管理。您可以将您的状态实例放在容器中作为单例,并将其注入控制器,这是线程安全的方式,最好在多线程Web环境中远离静态字段。

您必须在控制器中解决无状态服务,然后才能调用无状态服务的方法:

public async Task<IHttpActionResult> GetStateAsync()
{
     var proxyLocation = new ServiceUriBuilder("WebApiService");
     var svc = ServiceProxy.Create<IWebApiService>(proxyLocation.ToUri());
     return svc.GetState();
}

您需要创建一个包含getState方法的接口iwebapiservice。Webapiservice需要实施它。基本上,您需要使用iWebapiservice接口来抽象Webiservice。

最新更新