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.
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