Search Results for

    Show / Hide Table of Contents

    ASP.NET Core

    The Bridge

    When deploying Akka.NET in ASP.NET Core, one major concern is how to expose actor in an ASP.NET Core controllers. We will design an interface for this!

    namespace Akka.AspNetCore
    {
        public interface IActorBridge
        {
            void Tell(object message);
            Task<T> Ask<T>(object message);
        }
    }
    

    Akka.NET with IHostedService

    With the IActorBridge created, next is to host Akka.NET with IHostedService which will also implement the IActorBridge:

    
    using Akka.Actor;
    using Akka.DependencyInjection;
    
    namespace Akka.AspNetCore
    {
        public class AkkaService : IHostedService, IActorBridge
        {
            private ActorSystem _actorSystem;
            private readonly IConfiguration _configuration;
            private readonly IServiceProvider _serviceProvider;
            private IActorRef _actorRef;
    
            private readonly IHostApplicationLifetime _applicationLifetime;
    
            public AkkaService(IServiceProvider serviceProvider, IHostApplicationLifetime appLifetime, IConfiguration configuration)
            {
                _serviceProvider = serviceProvider;
                _applicationLifetime = appLifetime;
                _configuration = configuration;
            }
    
            public async Task StartAsync(CancellationToken cancellationToken)
            {
    
                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-universe", actorSystemSetup);
    
                _actorRef = _actorSystem.ActorOf(Worker.Prop(), "heavy-weight-word");
    
                // add a continuation task that will guarantee shutdown of application if ActorSystem terminates
                //await _actorSystem.WhenTerminated.ContinueWith(tr => {
                //   _applicationLifetime.StopApplication();
                //});
    #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                _actorSystem.WhenTerminated.ContinueWith(_ => {
                    _applicationLifetime.StopApplication();
                  });
    #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                await Task.CompletedTask;
            }
    
            public async Task StopAsync(CancellationToken cancellationToken)
            {
                // strictly speaking this may not be necessary - terminating the ActorSystem would also work
                // but this call guarantees that the shutdown of the cluster is graceful regardless
                await CoordinatedShutdown.Get(_actorSystem).Run(CoordinatedShutdown.ClrExitReason.Instance);
            }
    
            public void Tell(object message)
            {
                _actorRef.Tell(message);
            }
    
            public Task<T> Ask<T>(object message)
            {
                return _actorRef.Ask<T>(message);
            }
        }
    }
    
    

    Interaction Between Controllers and Akka.NET

    
    using Microsoft.AspNetCore.Mvc;
    
    // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
    
    namespace Akka.AspNetCore.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class AkkaController : ControllerBase
        {
            private readonly ILogger<AkkaController> _logger;
            private readonly IActorBridge _bridge;
    
            public AkkaController(ILogger<AkkaController> logger, IActorBridge bridge)
            {
                _logger = logger;
                _bridge = bridge;
            }
    
            [HttpGet]
            public Task<IEnumerable<string>> Get()
            {
                return _bridge.Ask<IEnumerable<string>>("get");
            }
    
            // POST api/<AkkaController>
            [HttpPost]
            public void Post([FromBody] string value)
            {
                _bridge.Tell(value);
            }
    
        }
    }
    
    

    Wire up Akka.NET and ASP.NET Core

    We need to replace the default IHostedService with AkkaService and also inject IActorBridge.

    using Akka.AspNetCore;
    
    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    
    builder.Services.AddControllers();
    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    // creates instance of IPublicHashingService that can be accessed by ASP.NET
    builder.Services.AddSingleton<IActorBridge, AkkaService>();
    
    // starts the IHostedService, which creates the ActorSystem and actors
    builder.Services.AddHostedService<AkkaService>(sp => (AkkaService)sp.GetRequiredService<IActorBridge>());
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        app.UseSwaggerUI();
    }
    
    app.UseAuthorization();
    
    app.MapControllers();
    
    app.Run();
    
    Note

    Visit our site's blog post for Best Practices for Integrating Akka.NET with ASP.NET Core and SignalR

    In this article
    • githubEdit this page
    Back to top
    Contribute
    • Project Chat
    • Discussion Forum
    • Source Code
    Support
    • Akka.NET Support Plans
    • Akka.NET Observability Tools
    • Akka.NET Training & Consulting
    Maintained By
    • Petabridge - The Akka.NET Company
    • Learn Akka.NET