All Articles

Service Fabric skeleton service

On Service fabric, you can either create ASP.NET Core API service or worker process. I’m going to create a worker service today

Visual Studio Template Skeleton

Right click on ServiceFabric project > Create a new Service Fabric service


Choose “Stateless Service” for worker service, as Stateful is the new evil in cloud era. It will create a skeleton service project. I named it xxxx.xxxx.xxxx.xxxx.Worker


You launch it by pressing “CTRL + F5” on Visual Studio. That’s my favourite way of deploying the new service fabric into the local dev machine cluster.

Shorten the default lengthy service name

You deploy it on to the cluster and notice that by default, the name of the service is pretty long.


Let’s shorten it. Go to ServiceFabric project > ApplicationPackageRoot > Applicationmanifest.xml

Then shorten the name.

First, remove all name spaces from service name

# Applicationmanifest.xml
  <Service Name="Worker" ServicePackageActivationMode="ExclusiveProcess">
    <StatelessService ServiceTypeName="WorkerType" InstanceCount="[xxxx.xxxx.xxxx.xxxx.Worker_InstanceCount]">
      <SingletonPartition />

Secondly, shorten type name too for convenience

<!-- Applicationmanifest.xml -->
  <Service Name="Worker" ServicePackageActivationMode="ExclusiveProcess">
    <StatelessService ServiceTypeName="WorkerType" InstanceCount="[xxxx.xxxx.xxxx.xxxx.Worker_InstanceCount]">
      <SingletonPartition />
<!-- ServiceManifest.xml -->
  <StatelessServiceType ServiceTypeName="WorkerType" />
// Program.cs
private static void Main()
            context => new Worker(context)).GetAwaiter().GetResult();

Install packages

Most of our apps uses Service Bus for messaging and Cosmos DB to store events.

The typical list of the packages are like these

<PackageReference Include="AspNetCore.HealthChecks.AzureServiceBus" Version="3.2.1" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.14.0" />
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.9.1" />
<PackageReference Include="Microsoft.Azure.Management.ServiceBus" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.4" />
<PackageReference Include="Microsoft.ServiceFabric.Services" Version="3.4.658" />

Add a generic host

A “host” is an object that encapsulates an app’s resources, such as:

  • Dependency injection (DI)
  • Logging
  • Configuration
  • IHostedService implementation


It is typicallyed configured, built, and run by code in the Program class. In service fabric worker service, it’ll be configured by a Stateless service. The flow is like this

  1. Program register a stateless service. In my case, “WorkerType”
  2. “Worker” class build a host and configure

    1. App Configuration
    2. Services
    3. Logging
  3. then “Worker” class start the host
  4. “EventSubscriptionHostedService” starts and subscribe to Service Bus messages
// Worker.cs
internal sealed class Worker : StatelessService
    private IHost _host;
    private readonly IHostBuilder _hostBuilder;

    public Worker(StatelessServiceContext context)
        : base(context)
        var builder = new HostBuilder();
        _hostBuilder = builder;

    protected override async Task OnOpenAsync(CancellationToken cancellationToken)
        _host = _hostBuilder.Build();
        await _host.StartAsync(cancellationToken);

    protected override async Task OnCloseAsync(CancellationToken cancellationToken)
        if (_host != null)
            await _host.StopAsync(cancellationToken);

    protected override void OnAbort()

// ServiceRegistrations.cs
public class ServiceRegistrations
    public static void ConfigureAppConfiguration(IConfigurationBuilder configurationBuilder)
        configurationBuilder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
        configurationBuilder.AddJsonFile($"appsettings.Development.json", true);


    public static void ConfigureServices(HostBuilderContext context,
        IServiceCollection services)
        var configuration = context.Configuration;

        services.AddTransient<IEnumerable<IHealthCheck>>(sp => new List<IHealthCheck>());

    public static void ConfigureLogging(HostBuilderContext ctx, ILoggingBuilder lb)
        lb.AddFilter<ApplicationInsightsLoggerProvider>("", LogLevel.Information);
// HostedService
public class EventHostedService : IHostedService
    private readonly ILogger<EventHostedService> _logger;
    private readonly TelemetryClient _telemetryClient;

    public DispatchEventHostedService(ILogger<DispatchEventHostedService> logger)
        _logger = logger;

    public async Task StartAsync(CancellationToken cancellationToken)
        _logger.LogInformation($"{GetType().Name} has started");
        _logger.LogWarning("Test Test");

    public Task StopAsync(CancellationToken cancellationToken)