Search code examples
c#azure-service-fabric

How to add Dependency Injection into a stateless service with a generic OwinCommunicationsListener


I have 7 services running under Service Fabric. I decided to create a generic OwinCommunicationsListener class since the code can be very generic.

I noticed that the template for Service Fabric sets up the startup class (which configures the pipeline) as a static class and the stateless service class passes it as an action

    internal sealed class WebService : StatelessService
{
    public WebService(StatelessServiceContext context)
        : base(context)
    { }

    /// <summary>
    /// Optional override to create listeners (like tcp, http) for this service instance.
    /// </summary>
    /// <returns>The collection of listeners.</returns>
    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new ServiceInstanceListener[]
        {
            new ServiceInstanceListener(serviceContext => new OwinCommunicationListener(Startup.ConfigureApp, serviceContext, ServiceEventSource.Current, "ServiceEndpoint"))
        };
    }
}

If I need to do DI, I need to pass those objects to the startup class. From the template, the only way I can see to do that is to either set those objects up in OwinCommunicationsListener or pass parameters to OwinCommunicationsListener - either of which will mean OwinCommunicationsListener is less generic.

I noticed in the WordCount example, they went with a normal startup class and passed a reference to it over to OwinCommunicationsListenter. This way the ServiceClass can pass some objects to Startup which it can use for DI and OwinCommunicationsListener can remain generic.

    public class WordCountWebService : StatelessService
{
    public WordCountWebService(StatelessServiceContext context)
        : base(context)
    {
    }

    /// <summary>
    /// Creates a listener for Web API with websockets.
    /// </summary>
    /// <returns>The OWIN communication listener.</returns>
    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new[]
        {
            new ServiceInstanceListener(initParams => new OwinCommunicationListener("wordcount", new Startup(MyDIObject), initParams))
        };
    }
}

If I think of the stateless service class as the brains and the OwinCommunicationsListener class as a generic helper shared by several services, it seems I should go the same route as the wordcount example and have a non-static startup class. Are there any downsides to this approach? I wondered why the templates would not use that approach when the idea of microservices is that we will have a lot of them and generic scaffolding like this can improve maintenance and reliability.


Solution

  • The wordcount example is what I would recommend. No downsides that I know of.

    Have you looked at ASP.NET Core? It gets even easier with IWebHost with its built-in DI. Here is an example: https://github.com/vturecek/service-fabric-xray/blob/master/src/xray.Data/DataService.cs