从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解决方案一样。
如果您使用开箱即用的OwinCommuncationController
和Startup
类,则可以初始化并向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 TinyIoC
和TinyIoC.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的指南。