Write to ServiceEventSource from Service Fabric WebAPI controller

北战南征 提交于 2019-12-04 13:05:26

One way of solving this is to work with Dependency Injection and an IoC, much like you would with a regular WebAPI solution.

If you are using the out-of-the-box supplied OwinCommuncationController and the Startup class you could initialize and add a container to the Startup.ConfigureApp(...) method:

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);
    }
}

You could use any IoC that you like, here I'll show it for TinyIoC but similar approach for any (Windsor, Unity, Ninject, AutoFac...).

For TinyIoC add the NuGet TinyIoC and TinyIoC.AspNetExtensions and add a class that implements 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
    }
}

Note, this is just the simples implementation, for a better look at this article http://blog.i-m-code.com/2014/04/15/tinyioc-mvc-and-webapi-configuration/

Not update your Startup to allow WebApi to use the DependencyResolver:

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

        config.DependencyResolver = new TinyIoCResolver(container);

       ...
    }
}

And finally register your dependency (StatelessServiceContext) in your service:

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"))
        };
    }
}

Notice that you have to make a slight change to how you call the Startup.ConfigureApp method in order to supply your container as well.

Now all you have to do is to add StatelessServiceContext as a dependency in the constructor of your ApiController and store it as a member in your controller:

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

And from within your controller actions use it:

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

There are many variations to how you can do this, when and where you can create the container, how to resolve the controllers and so on. There should be plenty of guides on how to setup ASP.NET WebApi and IoC dependency injection.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!