从Service Fabric WebAPI控制器写入ServiceEventSource

在我的有状态服务中,我可以通过调用以下方法写入ServiceEventSource

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

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

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

 public async Task Get(string id) { ServiceEventSource.Current.ServiceMessage(this.Context, "this is my log message"); //Do something return Ok(100); } 

解决此问题的一种方法是使用dependency injection和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.im-code.com/2014/04/15/tinyioc-mvc-and-webapi-configuration/

不更新您的Startup以允许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(context); } protected override IEnumerable CreateServiceInstanceListeners() { return new ServiceInstanceListener[] { new ServiceInstanceListener(serviceContext => new OwinCommunicationListener(appBuilder => Startup.ConfigureApp(appBuilder, Container), serviceContext, ServiceEventSource.Current, "ServiceEndpoint")) }; } } 

请注意,您必须稍微更改调用Startup.ConfigureApp方法的方式,以便为容器提供服务。

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

 public ValuesController(StatelessServiceContext serviceContext) { _serviceContext = serviceContext; } 

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

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

如何执行此操作有多种变体,您可以在何时何地创建容器,如何解析控制器等等。 应该有很多关于如何设置ASP.NET WebApi和IoCdependency injection的指南。