2

我正在开发一个 ASP.NET Core 2.1 项目,我需要在其中注册然后在 Startup.ConfigureServices 中使用单例服务。

我有以下代码:

public void ConfigureServices(IServiceCollection services)
{
    //....
    //....

    services.AddSingleton<IMyService,MyService>();

    var serviceProvider = services.BuildServiceProvider();

    var myService = serviceProvider.GetService<IMyService>();

    services.AddDbContext<MyDbContext>(options => options.UseMySql(myService.DBConnectionString));
}

上面的代码对我来说很好,可以在 ConfigureServices 中使用“MyService”。然而,稍后在我的应用程序中,当我尝试使用 MyService 时,再次调用 MyService 的构造函数。为什么它不使用自从我使用注册类以来已经创建的实例AddSingleton

编辑:我决定编辑以添加我的最终目标,看看是否有不同的方法来完成它。我的单例服务提供了对可能来自 2 个不同地方的一些设置的访问。其中一项设置是数据库连接字符串。我在 ConfigureServices 中需要那个连接字符串,所以当我调用services.AddDbContext. 我还想在获取配置设置的服务中进行一些日志记录,这意味着我也需要获取 ILoggerFactory。

4

2 回答 2

6

调用BuildServiceProviderfromConfigureServices将导致创建一个额外的单例服务副本。

在这种特殊情况下,请使用另一种方法来推迟对服务提供商的访问。AddDbContext具有允许这种情况的重载,其中服务提供者作为选项操作委托的一部分提供。

//...

services.AddSingleton<IMyService, MyService>();

services.AddDbContext<MyDbContext>((serviceProvider, options) =>
    options.UseMySql(serviceProvider.GetRequiredService<IMyService>().DBConnectionString)
);

//....

参考AddDbContext<TContext>(IServiceCollection, Action<IServiceProvider,DbContextOptionsBuilder>, ServiceLifetime, ServiceLifetime)

于 2019-06-26T23:51:57.850 回答
0

AddSingleton告诉 Unity 构建一次。“一次”是您在代码中直接调用的任何构造函数的补充。

如果您想重新使用您创建的实例,请AddInstance改用。

var serviceProvider = services.BuildServiceProvider();

var myService = serviceProvider.GetService<IMyService>();

services.AddInstance<IMyService>(myService);

services.AddDbContext<MyDbContext>(options => options.UseMySql(myService.DBConnectionString));
于 2019-06-27T00:01:28.937 回答