c# - services.AddSingleton,永远不会调用服务的构造函数

标签 c# asp.net-core dependency-injection

tl;博士

services.AddSingleton<ISomeService, SomeService>();
// SomeService not instantiated nor initialized?

在经典 SignalR Chat 应用程序的变体中,我正在监视对 SQL Server 表的更改并通过 SignalR 实时报告它们。 watch this video花 10 秒钟来理解这个想法。我的代码改编自 this project .聊天部分工作正常。

对 SQL Server 表的更改应该由类监视 SqlDependencyService .但是,它的构造函数从未被调用,它应该在此处获取对 SignalR 集线器的引用。

这是我的 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.
}

这是我的 SqlDependencyService 类的一部分:

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()
        {
            // ...
        }

        // ...
    }

这是服务的界面:

public interface IDatabaseChangeNotificationService
{
    void Config();
}

如前所述,永远不会调用构造函数。此外,我看不到如何调用 Config 方法 - 一些 ASP.NET Core 约定魔法?

我的 HomeController 没有这个问题,它的构造函数被调用并传递了一个 IHubContext<ChatHub> :

public class HomeController : Controller
{
    private readonly IHubContext<ChatHub> chatHub;

    public HomeController(IHubContext<ChatHub> chatHub)
    {
        this.chatHub = chatHub;
    }

    // ...
}

最佳答案

只是添加一个服务不会导致它被实例化,你实际上需要将它注入(inject)到容器中以调用它的构造函数。看起来你希望服务在启动时可用,所以我建议使用 Configure启动方法:

public void Configure(IApplicationBuilder app, IDatabaseChangeNotificationService dbService)
{
    dbService.Config();

    //snip
}

关于c# - services.AddSingleton,永远不会调用服务的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56408358/

相关文章:

c# - 如何以确定性方式将 IEEE754 float 转换为定点数?

c# - 无法在 Visual Studio 中更新 dll 引用

c# - C# 是否需要 .NET

c# - 如何接受以 JSON 作为内容类型的无正文 GET 请求?

c# - 如何定义两个实体之间的多重关系?

c# - 事件目录别名

c# - 更新大量数据时重复键值错误

java - 了解Java的注入(inject)框架HK2吗?

c# - 避免 .NET Core 中 n 层架构的循环依赖

c# - 将参数从复合根向下传递到 DI 链