tl;dr
services.AddSingleton<ISomeService, SomeService>();
// SomeService not instantiated nor initialized?
In a variation on the classic SignalR Chat app, I'm monitoring changes to a SQL Server table and reporting them in real-time through SignalR. Watch this video for 10 seconds to get the idea. My code is adapted from this project. The chat part works fine.
Changes to the SQL Server table are supposed to be monitored by class SqlDependencyService
. However, its constructor is never called, and that's where it should get a reference to the SignalR hub.
Here's my Startup.ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// No instantiation ?!?
services.AddSingleton<IDatabaseChangeNotificationService, SqlDependencyService>();
// My lame attempt at forcing instantiation:
SqlDependencyService sqlDS = serviceProvider.GetService<SqlDependencyService>();
//sqlDS.Config(); // Fails, sqlDS is null.
}
And here's part of my SqlDependencyService class:
public class SqlDependencyService : IDatabaseChangeNotificationService
{
private readonly IConfiguration configuration;
private readonly IHubContext<ChatHub> chatHub;
// Never gets called!
public SqlDependencyService(IConfiguration configuration, IHubContext<ChatHub> chatHub)
{
this.configuration = configuration;
this.chatHub = chatHub;
}
// Never gets called!
public void Config()
{
SubscribeToPersonTableChanges();
}
private void SubscribeToPersonTableChanges()
{
// ...
}
// ...
}
Here's the service's interface:
public interface IDatabaseChangeNotificationService
{
void Config();
}
As stated, the constructor is never called. Additionally, I don't see how the Config method could possibly be invoked - some ASP.NET Core convention magic?
I don't have this issue with the HomeController, whose constructor is called and passed an IHubContext<ChatHub>
:
public class HomeController : Controller
{
private readonly IHubContext<ChatHub> chatHub;
public HomeController(IHubContext<ChatHub> chatHub)
{
this.chatHub = chatHub;
}
// ...
}
Just adding a service won't cause it to be instantiated, you actually need to inject it into something for the container to call it's constructor. It looks like you want the service to be available at startup, so I would recommend using the Configure
method in startup:
public void Configure(IApplicationBuilder app, IDatabaseChangeNotificationService dbService)
{
dbService.Config();
//snip
}
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