Windows Service
learn more from Microsoft
Program.cs
using AkkaWindowsService;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using IHost host = Host.CreateDefaultBuilder(args)
.UseWindowsService(options =>
{
options.ServiceName = ".NET Joke Service";
})
.ConfigureServices(services =>
{
services.AddHostedService<AkkaService>();
services.AddHttpClient<JokeService>();
})
.Build();
await host.RunAsync();
AkkaService.cs
using Akka.Actor;
using Akka.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace AkkaWindowsService
{
public sealed class AkkaService : BackgroundService
{
private readonly ILogger<AkkaService> _logger;
private readonly JokeService _jokeService;
private readonly ActorSystem _actorSystem;
private readonly IActorRef _actorRef;
public AkkaService(JokeService jokeService, ILogger<AkkaService> logger, IServiceProvider serviceProvider)
{
_jokeService = jokeService;
_logger = logger;
var bootstrap = BootstrapSetup.Create();
// enable DI support inside this ActorSystem, if needed
var diSetup = DependencyResolverSetup.Create(serviceProvider);
// merge this setup (and any others) together into ActorSystemSetup
var actorSystemSetup = bootstrap.And(diSetup);
// start ActorSystem
_actorSystem = ActorSystem.Create("akka-system", actorSystemSetup);
_actorRef = _actorSystem.ActorOf(MyActor.Prop());
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var joke = await _jokeService.GetJokeAsync();
_logger.LogWarning(joke);
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
_actorRef.Tell(joke);
}
}
}
}
JokeService.cs
using System.Net.Http.Json;
using System.Text.Json;
namespace AkkaWindowsService
{
public class JokeService
{
private readonly HttpClient _httpClient;
private readonly JsonSerializerOptions _options = new()
{
PropertyNameCaseInsensitive = true
};
private const string JokeApiUrl =
"https://karljoke.herokuapp.com/jokes/programming/random";
public JokeService(HttpClient httpClient) => _httpClient = httpClient;
public async Task<string> GetJokeAsync()
{
try
{
// The API returns an array with a single entry.
var jokes = await _httpClient.GetFromJsonAsync<Joke[]>(
JokeApiUrl, _options);
var joke = jokes?[0];
return joke is not null
? $"{joke.Setup}{Environment.NewLine}{joke.Punchline}"
: "No joke here...";
}
catch (Exception ex)
{
return $"That's not funny! {ex}";
}
}
}
public record Joke(int Id, string Type, string Setup, string Punchline);
}
MyActor.cs
using Akka.Actor;
using System.Text.Json;
namespace AkkaWindowsService
{
internal class MyActor : ReceiveActor
{
public MyActor()
{
Receive<Joke>(j => Console.WriteLine(JsonSerializer.Serialize(j, options: new JsonSerializerOptions { WriteIndented = true })));
}
public static Props Prop()
{
return Props.Create<MyActor>();
}
}
}