从Service Fabric WebAPI控制器写入ServiceEventSource



在我的Stateful服务中,我可以通过调用以下命令写入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);
}

解决此问题的一种方法是使用依赖注入和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…)都有类似的方法。

对于TinyoC,添加NuGetTinyIoCTinyIoC.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依赖项注入的指南。

相关内容

  • 没有找到相关文章

最新更新