我在一个实例的无状态服务中托管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.
我的问题是:
控制器如何获得对WebApiservice实例的引用?
在静态字段中存储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。