Make separate file and inject as Service in blazor wasm

Prathamesh Shende 511 Reputation points
2023-11-15T10:54:45.79+00:00

I want to make the separate file HubConnection Code where i will call it as service
by injecting into .razor pages of blazor wasm Is this possible?

The problem I am facing I am copying the same code in every .razor file It really a bad practices.

private HubConnection hubConnection;
    public bool IsConnected => hubConnection.State == HubConnectionState.Connected;
    Task SendMessage() => hubConnection.SendAsync("SendMessage");
    public void Dispose() { _ = hubConnection.DisposeAsync(); }
protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder().WithUrl(_navigationManager.ToAbsoluteUri("/RealTimeHub")).Build();
        hubConnection.On("ReceiveMessage", () =>
        {
            Task.Run(async () =>
            {
                await Load(1, pagesizeno, 0); // I will pass function as a parameter  
            });
            StateHasChanged();
        });
        await hubConnection.StartAsync();
        await Load(1, pagesizeno, 0);
    }

I have tried this but it will not working RealTimeHubConnection.cs

public class RealTimeHubConnection
{
    private HubConnection _hubConnection;
    readonly NavigationManager _navigationManager;

    public RealTimeHubConnection(HubConnection hubConnection, NavigationManager navigationManager)
    {
        _hubConnection = hubConnection;
        _navigationManager = navigationManager;
    }
    public void LoadConnection(Func<Task?> func)
    {
        _hubConnection = new HubConnectionBuilder().WithUrl(_navigationManager.ToAbsoluteUri("/RealTimeHub")).Build();
        _hubConnection.On("ReceiveMessage", () =>
        {
            Task.Run(() => func());
        });
        await hubConnection.StartAsync();
    }
    public bool IsConnected => _hubConnection.State == HubConnectionState.Connected;
    Task SendMessage() => _hubConnection.SendAsync("SendMessage");
    public void Dispose() { _ = _hubConnection.DisposeAsync(); }
    public async Task NotifyConnection()
    {
        if (IsConnected)
        {
            await SendMessage();
        }
    }
}

Developer technologies | .NET | Blazor
0 comments No comments
{count} votes

Answer accepted by question author
  1. Anonymous
    2023-11-16T02:46:15.4866667+00:00

    Hi @Prathamesh Shende,

    Add _hubConnection = new HubConnectionBuilder(). WithUrl(_navigationManager.ToAbsoluteUri("/RealTimeHub")). Build(); Moved to RealTimeHubConnection.

    My Test Result

    User's image

    RealTimeHubConnection.cs

    using Microsoft.AspNetCore.Components;
    using Microsoft.AspNetCore.SignalR.Client;
    
    namespace BlazorApp1
    {
        public class RealTimeHubConnection : IDisposable
        {
            private HubConnection _hubConnection;
            private readonly NavigationManager _navigationManager;
    
            public RealTimeHubConnection(NavigationManager navigationManager)
            {
                _navigationManager = navigationManager;
                _hubConnection = new HubConnectionBuilder().WithUrl(_navigationManager.ToAbsoluteUri("/RealTimeHub")).Build();
            }
    
            public async Task LoadConnection(Func<Task> func)
            {
                _hubConnection.On("ReceiveMessage", async () =>
                {
                    await func();
                });
    
                await _hubConnection.StartAsync();
            }
    
            public bool IsConnected => _hubConnection.State == HubConnectionState.Connected;
    
            public Task SendMessageAsync() => _hubConnection.SendAsync("SendMessage");
    
            public void Dispose()
            {
                _hubConnection?.DisposeAsync();
            }
        }
    
    }
    
    

    Program.cs

    using Microsoft.AspNetCore.Components.Web;
    using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
    
    namespace BlazorApp1
    {
        public class Program
        {
            public static async Task Main(string[] args)
            {
                var builder = WebAssemblyHostBuilder.CreateDefault(args);
                builder.RootComponents.Add<App>("#app");
                builder.RootComponents.Add<HeadOutlet>("head::after");
    
                builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
    
                builder.Services.AddScoped<RealTimeHubConnection>();
    
    
                await builder.Build().RunAsync();
            }
        }
    }
    
    
    

    Usage:

    @page "/weather"
    @inject HttpClient Http
    // add this line
    @inject RealTimeHubConnection realTimeHubConnection
    
    <PageTitle>Weather</PageTitle>
    
    <h1>Weather</h1>
    
    <p>This component demonstrates fetching data from the server.</p>
    
    @if (forecasts == null)
    {
        <p><em>Loading...</em></p>
    }
    else
    {
        <table class="table">
            <thead>
                <tr>
                    <th>Date</th>
                    <th>Temp. (C)</th>
                    <th>Temp. (F)</th>
                    <th>Summary</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var forecast in forecasts)
                {
                    <tr>
                        <td>@forecast.Date.ToShortDateString()</td>
                        <td>@forecast.TemperatureC</td>
                        <td>@forecast.TemperatureF</td>
                        <td>@forecast.Summary</td>
                    </tr>
                }
            </tbody>
        </table>
    }
    
    @code {
        private WeatherForecast[]? forecasts;
    
        protected override async Task OnInitializedAsync()
        {
            forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
            // add this 
            await realTimeHubConnection.LoadConnection(async () =>
            {
               
            });
        }
    
        public class WeatherForecast
        {
            public DateOnly Date { get; set; }
    
            public int TemperatureC { get; set; }
    
            public string? Summary { get; set; }
    
            public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
        }
    }
    
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,

    Jason

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.