I am currently looking into Orleans as a backend for Asp.net core web api project, and was wondering if anyone has any experience with its new feature - "direct client". The orleans docs say "it allows co-hosting a client and silo in a way that let the client communicate more efficiently with not just the silo it's attached to, but the entire cluster", and I am aware that you can code something like this (and it works just fine in a console app):
var silo = new SiloHostBuilder()
.UseLocalhostClustering()
.EnableDirectClient()
.Build();
await silo.StartAsync();
var client = silo.Services.GetRequiredService<IClusterClient>();
I am struggling trying to figure out where to put this type of code in an asp.net project that has its own webhost builder in "Main" (should it go to Startup class in "ConfigureServices"?). In the end, we are aiming for a separate client/server setup, but for faster development it would be useful to play with a simple setup, which direct client appears to allow for. Any pointers to resources and/or sample solutions containing direct client with asp.net core would be appreciated. Thanks.
EDIT: Here's the code that kinda works for me now, but I am not happy with he way the DI is set up
public static async Task Main(string[] args)
{
var silo = new SiloHostBuilder()
.UseLocalhostClustering()
.ConfigureServices(services =>
{
services.AddDbContext<UserDbSet>(o => o.UseSqlite("Data Source=UserTest.db"));
services.AddMediatR(typeof(Startup).Assembly);
})
.EnableDirectClient()
.Build();
await silo.StartAsync();
var client = silo.Services.GetRequiredService<IClusterClient>();
await WebHost.CreateDefaultBuilder(args)
.UseConfiguration(new ConfigurationBuilder()
.AddCommandLine(args)
.Build())
.ConfigureServices(services =>
services
.AddSingleton<IGrainFactory>(client)
.AddSingleton<IClusterClient>(client))
.UseStartup<Startup>()
.Build()
.RunAsync();
}
If I put registration of the DbContext
and Mediatr
in the StartUp
class, grain code fails with an exception indicating failure to instantiate the required dependencies. Maybe I am doing something wrong when setting up the Webhost
?
For ASP.NET 2.x & Orleans below 2.3, I recommend creating & starting the silo before the Web host. When configuring the Web host, inject the IGrainFactory
& IClusterClient
instances from the silo (obtained via silo.Services
):
var silo = new SiloHostBuilder()
.UseLocalhostClustering()
.EnableDirectClient()
.Build();
await silo.StartAsync();
var client = silo.Services.GetRequiredService<IClusterClient>();
var webHost = new WebHostBuilder()
.ConfigureServices(services =>
services
.AddSingleton<IGrainFactory>(client)
.AddSingleton<IClusterClient>(client))
.UseStartup<Startup>()
// Other ASP.NET configuration...
.Build();
For ASP.NET 3.0 & Orleans 2.3 or greater, the integration code becomes simpler due to the addition of Microsoft.Extensions.Hosting
support in both frameworks:
var host = new HostBuilder()
.ConfigureWebHost(builder =>
{
// Adding IGrainFactory, etc, is not necessary, since Orleans
// and ASP.NET share the same dependency injection container.
builder.UseStartup<Startup>();
})
.UseOrleans(builder =>
{
// EnableDirectClient is no longer needed as it is enabled by default
builder.UseLocalhostClustering();
})
.Build();
await host.StartAsync();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With