从 Service Fabric Web API 控制器写入服务事件源

Posted

技术标签:

【中文标题】从 Service Fabric Web API 控制器写入服务事件源【英文标题】:Write to ServiceEventSource from Service Fabric WebAPI controller 【发布时间】:2017-06-17 13:59:00 【问题描述】:

在我的有状态服务中,我可以通过调用这个来写信给ServiceEventSource

ServiceEventSource.Current.ServiceMessage(this.Context, "this is my log message");

有谁知道我如何在我的无状态 WebAPI 控制器中进行同样的调用?似乎我无法将上下文输入控制器。我注意到它只在我的OwinCommunicationListener 中可用。

基本上,我希望能够像这样记录我的控制器:

public async Task<IHttpActionResult> Get(string id)

   ServiceEventSource.Current.ServiceMessage(this.Context, "this is my log message");
   //Do something
   return Ok(100);

【问题讨论】:

【参考方案1】:

解决此问题的一种方法是使用依赖注入和 IoC,就像使用常规 WebAPI 解决方案一样。

如果您使用开箱即用的 OwinCommuncationControllerStartup 类,您可以初始化容器并将其添加到 Startup.ConfigureApp(...) 方法:

public static class Startup

    // This code configures Web API. The Startup class is specified as a type
    // parameter in the WebApp.Start method.
    public static void ConfigureApp(IAppBuilder appBuilder)
    
        // Configure Web API for self-host. 
        HttpConfiguration config = new HttpConfiguration();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/controller/id",
            defaults: new  id = RouteParameter.Optional 
        );

        // Add a DependencyResolver here

        appBuilder.UseWebApi(config);
    

你可以使用任何你喜欢的 IoC,这里我将展示它用于 TinyIoC,但类似的方法适用于任何(Windsor、Unity、Ninject、AutoFac...)。

对于 TinyIoC,添加 NuGet TinyIoCTinyIoC.AspNetExtensions 并添加一个实现 IDependencyResolver 的类:

public class TinyIoCResolver : IDependencyResolver

    private readonly TinyIoCContainer _container;

    public TinyIoCResolver(TinyIoCContainer container)
    
        _container = container;
    

    public object GetService(Type serviceType)
    
        return _container.Resolve(serviceType);
    

    public object GetService(Type serviceType)
    
        try
        
            return _container.Resolve(serviceType);
        
        catch (TinyIoCResolutionException)
        
            return null;
        
    

    public IDependencyScope BeginScope()
    
        return new TinyIoCResolver(_container.GetChildContainer());
    

    public void Dispose()
    
        // Handle dispose
    

注意,这只是简单的实现,为了更好地查看这篇文章 http://blog.i-m-code.com/2014/04/15/tinyioc-mvc-and-webapi-configuration/

不更新您的启动以允许 WebApi 使用 DependencyResolver:

public static class Startup

    public static void ConfigureApp(IAppBuilder appBuilder, TinyIoCContainer container)
    
       ...

        config.DependencyResolver = new TinyIoCResolver(container);

       ...
    

最后在您的服务中注册您的依赖项 (StatelessServiceContext):

internal sealed class WebApiService : StatelessService

    public TinyIoCContainer Container  get; private set; 

    public WebApiService(StatelessServiceContext context)
        : base(context)
    
        Container = new TinyIoCContainer();
        Container.Register<StatelessServiceContext>(context);
    

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    
        return new ServiceInstanceListener[]
        
            new ServiceInstanceListener(serviceContext => new OwinCommunicationListener(appBuilder => Startup.ConfigureApp(appBuilder, Container), serviceContext, ServiceEventSource.Current, "ServiceEndpoint"))
        ;
    

请注意,您必须对调用 Startup.ConfigureApp 方法的方式稍作更改,以便同时提供您的容器。

现在您所要做的就是在您的ApiController 的构造函数中添加StatelessServiceContext 作为依赖项并将其作为成员存储在您的控制器中:

public ValuesController(StatelessServiceContext serviceContext) 

    _serviceContext = serviceContext;

并在您的控制器操作中使用它:

ServiceEventSource.Current.ServiceMessage(_serviceContext, "this is my log message");

您可以如何执行此操作、创建容器的时间和地点、如何解析控制器等有很多变化。应该有很多关于如何设置 ASP.NET WebApi 和 IoC 依赖注入的指南。

【讨论】:

很高兴我能帮上忙 :) 嘿@yoape - 感谢您提供详细的代码和说明。我正在关注它,但在 WebAPI 控制器上遇到此错误:“尝试创建“CacheController”类型的控制器时发生错误。确保控制器具有无参数的公共构造函数。键入“Endpoint.Controllers”。 CacheController' 没有默认构造函数”。 您是否将 DependencyResolver 设置为使用您的 IoC 容器的那个? 即这部分在Startup.ConfigureApp(...):var container = TinyIoCContainer.Current; config.DependencyResolver = new TinyIoCResolver(container); 您看到的错误听起来像是当默认解析器无法构造控制器时 ASP.NET 会向您抛出的错误,而当没有无参数构造函数时它将无法做到这一点

以上是关于从 Service Fabric Web API 控制器写入服务事件源的主要内容,如果未能解决你的问题,请参考以下文章

Web API Service Fabric 应用程序提供未经授权的

从 Azure Service Fabric 中的不同应用程序与无状态 Web Api 服务通信

Service Fabric 中的 Web API 损坏

SignalR 与 Service Fabric 无状态 Web API

Service Fabric Web API 版本控制问题

在 Service Fabric 上托管 Web API