Azure / azure-signalr

Azure SignalR Service SDK for .NET
https://aka.ms/signalr-service
MIT License
425 stars 100 forks source link

DI Issues when using third-party libraries. #1516

Closed paburgos closed 11 months ago

paburgos commented 2 years ago

Hello,

I am using Finbuckle to convert my Blazor Server App into a multitenant. I am also implementing the Azure SignalR Service.

But as soon as I put to work both together I get this error:

Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer: Warning: Unhandled exception rendering component: Cannot provide a value for property 'Tenant' on type 'Project1.Pages.Index'. There is no registered service of type 'Project1.Data.Multitenant.MyTenantInfo'. System.InvalidOperationException: Cannot provide a value for property 'Tenant' on type 'Project1.Pages.Index'. There is no registered service of type 'Project1Data.Multitenant.MyTenantInfo'.

I have a repo with the issue: https://github.com/paburgos/SignalRFinbuckleIssue To reproduce the error is just a matter to enable SignalR service logic in startup.cs, launchsettings.json, and appsettings.json.

Here is how the services are registered for Finbuckle.MultiTenant.

I also have an issue opened directly in Finbuckle here

I am wondering if you can help me find out where the issue might be?

vicancy commented 2 years ago

Sorry for the late response. When using AzureSignalR, blazor client requests are going through Azure SignalR to the server instead of triggering the server's HTTP middleware anymore. So the way that Finbuckle registers the per-tenant service inside the middleware https://github.com/Finbuckle/Finbuckle.MultiTenant/blob/f02be2508e615a4a366b61fd06d5a9d40ec2372c/src/Finbuckle.MultiTenant.AspNetCore/Internal/MultiTenantMiddleware.cs#L26 can no longer work.

The workaround I have is to resolve the MyTenantInfo inside the page:

@page "/"
@using Finbuckle.MultiTenant
@inject IHttpContextAccessor httpContextAccessor
@inject IMultiTenantContextAccessor<MyTenantInfo> accessor
@code{
    protected override async Task OnInitializedAsync()
    {
        var context = httpContextAccessor.HttpContext;
        var accessor = context.RequestServices.GetRequiredService<IMultiTenantContextAccessor>();

            if (accessor.MultiTenantContext == null)
            {
                var resolver = context.RequestServices.GetRequiredService<ITenantResolver>();
                var multiTenantContext = await resolver.ResolveAsync(context);
                accessor.MultiTenantContext = multiTenantContext;
            }
        await base.OnInitializedAsync();
    }
}

<PageTitle>Index</PageTitle>

<h1>Hello, @accessor.MultiTenantContext.TenantInfo.Name</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />
vicancy commented 11 months ago

Please feel free to reopen the issue if there are any updates.