.Net Core Windows service met Topshelf

Topshelf is een mooie nuget package voor .Net om gemakkelijk een Windows Service te ontwikkelen, te installeren of om de applicatie niet als windows service te gebruiken maar als “normale” executable. Topshelf heeft een mooie site met mooie voorbeelden en documentatie.

Ik heb het tijdens meerdere projecten gebruikt en ik wilde nog een paar dingen opschrijven die ik geleerd heb over de service dependencies in die tijd.

Service Dependencies

Service dependencies zijn alleen bruikbaar als de applicatie als windows service draait. Het is ook iets van Windows zelf waarbij aangegeven kan worden dat een service alleen mag starten als de services waarvan deze service afhankelijk is ook gestart zijn. Dit kan tijdens installatie van de service aangegeven worden en met Topshelf kan het ook in de code. Het mooie is dat deze dependencies alleen gecheckt worden als de andere service ook daadwerkelijk aanwezig is. Mocht de service niet aanwezig zijn wordt de afhankelijkheid ook niet vastgelegd. Tot het moment dat de service waarvan men afhankelijk is wordt geinstalleerd, dan komt de dependency/afhankelijkheid automatisch terug.

Met Topshelf kan de dependency makkelijk in de code worden vastgelegd:

HostFactory.Run(x =>
{
    //Set de naam en de displaynaam van de service
    x.SetServiceName("Naam van de Service");
    x.SetDisplayName("Welke naam wordt getoond"); 
    x.SetDescription("Omschrijving van de service");
    x.StartAutomaticallyDelayed(); // Start de service automatisch maar met vertraging
    x.EnableServiceRecovery(r =>
    {
        //Welke acties moeten uitgevoerd worden als de service faalt
        r.RestartService(0); //Bij de eerste fout meteen opnieuw starten.
        r.RestartService(1); //Bij de tweede fout, wacht 1 minuut en dan opnieuw starten
        r.RestartService(2); //Blijf proberen opnieuw de service te starten maar wacht 2 min.
        r.SetResetPeriod(1); //Reset de teller iedere dag
    });
    //Vastleggen van de service dependency
    x.DependsOn("ServiceToDependOn");
    //Class welke gestart moet worden
    x.Service<ServiceHostStartup>();
});

Om achteraf nog service dependencies toe te voegen zonder de code aan te passen staat op Stackoverflow een goede beschrijving.