我在一个实例的无状态服务中托管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构造函数中设置)是否安全?
答案 0 :(得分:1)
我认为你可以使用DI容器。我可以推荐simpleinjector(但有很多可以做同样的事情),simpleinjector也可以根据请求和web api包进行对象生存期管理。您可以将状态实例作为单例放在容器中,并将其注入控制器,这将是一种线程安全的方式,更好地远离多线程Web环境中的静态字段。
答案 1 :(得分:1)
通过DI容器将服务实例作为依赖项注入控制器。
以下是使用Unity在Katana上托管Web API的示例。它是一项有状态的服务,但它对无状态服务的工作方式完全相同:https://github.com/Azure-Samples/service-fabric-dotnet-getting-started/tree/master/Services/WordCount/WordCount.Service
以下是使用Asp.Net Core及其内置依赖注入容器的示例(也是有状态的,但同样适用):https://github.com/vturecek/service-fabric-xray/tree/master/src/xray.Data
答案 2 :(得分:0)
您必须先解析控制器中的无状态服务,然后才能调用无状态服务的方法:
public async Task<IHttpActionResult> GetStateAsync()
{
var proxyLocation = new ServiceUriBuilder("WebApiService");
var svc = ServiceProxy.Create<IWebApiService>(proxyLocation.ToUri());
return svc.GetState();
}
您需要创建一个包含GetState方法的IWebApiService接口。 WebApiService需要实现它。基本上,您需要使用IWebApiService接口抽象WebApiService。