I'm having an issue with configuring SignalR. I'm working with .NET Azure Functions in isolated process model.
Here's the error message I get:
Exception Unable to resolve service for type 'Microsoft.Azure.SignalR.Management.ServiceManager' while attempting to activate 'PatientNavigationDBAPI.Services.SignalRService'
This is my code:
public static class AzureServiceExtensions
{
public static IServiceCollection AddAzureServices(this IServiceCollection services)
{
//other services
services.AddSignalR().AddAzureSignalR(Environment.GetEnvironmentVariable(EnvironmentVariable.AzureSignalRConnectionString));
services.AddScoped<SignalRService>();
return services;
}
}
In Program.cs
, I have:
var host = new HostBuilder()
.ConfigureFunctionsWebApplication(worker =>
{
worker.UseNewtonsoftJson(new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Include,
Formatting = Formatting.Indented,
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
}
});
})
.ConfigureOpenApi()
.ConfigureServices((host, services) =>
{
services.AddAzureServices();
})
.Build()
.SeedData();
host.Run();
Exception Unable to resolve service for type 'Microsoft.Azure.SignalR.Management.ServiceManager' while attempting to activate 'PatientNavigationDBAPI.Services.SignalRService'
I got the same error when I reproduced the same in my environment.
It occurs because Dependency Injection (DI) is trying to create an instance of your SignalRService
, but the required dependency ServiceManager
is not registered in the service container.
Below code worked for me:
SignalRService.cs:
public class SignalRService
{
private readonly IServiceManager _serviceManager;
public SignalRService(IServiceManager serviceManager)
{
_serviceManager = serviceManager;
}
public async Task SendMessageAsync(string hubName, string methodName, object message)
{
var hubContext = await _serviceManager.CreateHubContextAsync(hubName, default);
await hubContext.Clients.All.SendAsync(methodName, message);
await hubContext.DisposeAsync();
}
}
Program.cs:
var host = new HostBuilder()
.ConfigureFunctionsWebApplication(worker =>
{
worker.UseNewtonsoftJson(new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Include,
Formatting = Formatting.Indented,
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
}
});
})
.ConfigureOpenApi()
.ConfigureServices((context, services) =>
{
services.AddAzureServices();
})
.Build();
host.Run();
AzureServiceExtensions.cs:
public static class AzureServiceExtensions
{
public static IServiceCollection AddAzureServices(this IServiceCollection services)
{
var connectionString = Environment.GetEnvironmentVariable("AzureSignalRConnectionString");
services.AddSingleton<IServiceManager>(sp =>
{
return new ServiceManagerBuilder()
.WithOptions(opt => opt.ConnectionString = connectionString)
.Build();
});
services.AddScoped<SignalRService>();
return services;
}
}
Function.cs:
public class Function1
{
private readonly SignalRService _signalRService;
private readonly ILogger<Function1> _logger;
public Function1(SignalRService signalRService, ILogger<Function1> logger)
{
_signalRService = signalRService;
_logger = logger;
}
[Function("BroadcastMessage")]
public async Task<HttpResponseData> Run(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req)
{
await _signalRService.SendMessageAsync("chat", "newMessage", new { message = "Hello from Azure Function!" });
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync("Message sent via Azure SignalR.");
_logger.LogInformation("SignalR message sent.");
return response;
}
}
Output:
Functions:
BroadcastMessage: [POST] http://localhost:7012/api/BroadcastMessage
RenderOAuth2Redirect: [GET] http://localhost:7012/api/oauth2-redirect.html
RenderOpenApiDocument: [GET] http://localhost:7012/api/openapi/{version}.{extension}
RenderSwaggerDocument: [GET] http://localhost:7012/api/swagger.{extension}
RenderSwaggerUI: [GET] http://localhost:7012/api/swagger/ui
For detailed output, run func with --verbose flag.
[2025-06-06T09:24:07.457Z] Executing 'Functions.BroadcastMessage' (Reason='This function was programmatically called via the host APIs.', Id=661e9597-d9fa-463f-a639-42ddfe0fbdfb)
[2025-06-06T09:24:08.093Z] Host lock lease acquired by instance ID '0000000000000000000000004F4DDDC0'.
[2025-06-06T09:24:09.278Z] SignalR message sent.
[2025-06-06T09:24:09.310Z] Executed 'Functions.BroadcastMessage' (Succeeded, Id=661e9597-d9fa-463f-a639-42ddfe0fbdfb, Duration=1900ms)