我尝试为新的ASP.NET Core站点设置DI,我有这样的代码:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// Get the configuration from the app settings.
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
// Get app settings to configure things accordingly.
var appSettings = Configuration.GetSection("AppSettings");
var settings = new AppSettings();
appSettings.Bind(settings);
services
.AddOptions()
.Configure<AppSettings>(appSettings)
.AddSingleton<IConfigurationRoot>(config)
.AddDbContext<MyDbContext>(builder =>
{
builder.UseSqlServer(config.GetConnectionString("myConn"));
}, ServiceLifetime.Transient, ServiceLifetime.Transient);
services.AddSingleton<ILoadTestCleanUpServiceRepository, LoadTestCleanUpServiceRepository>();
...
现在,LoadTestCleanUpServiceRepository
取决于MyDbContext
:
public class LoadTestCleanUpServiceRepository : ILoadTestCleanUpServiceRepository
{
private readonly MyDbContext _dbContext;
public LoadTestCleanUpServiceRepository(MyDbContext dbContext)
{
_dbContext = dbContext;
}
...
..和DB上下文是这样的:
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> ctxOptions) : base(ctxOptions)
{
}
}
当我运行该应用程序时,我收到此错误:
InvalidOperationException:尝试激活“MyCode.Infrastructure.LoadTestCleanUpService.LoadTestCleanUpServiceRepository”时,无法解析类型“MyCode.Infrastructure.Common.MyDbContext”的服务。
我试过更改ServiceLifetime
选项并添加这个额外的代码:
services.AddTransient<MyDbContext>(sp => new MyDbContext(config));
......但似乎没有任何帮助,我无法理解为什么这不起作用。它确实尝试构建存储库,但为什么它也不能构建数据库上下文呢?它甚至没有达到我称之为UseSqlServer()
的程度!有任何想法吗?
更新1:
嗯......我现在看到这个。最有可能是相关的:
更新2:
我现在有了 :
但我仍然得到同样的错误。
我看到你注册LoadTestCleanUpServiceRepository
为Singleton
而MyDbContext
为Transient
然后你试图从MyDbContext
解决LoadTestCleanUpServiceRepository
。那就是问题所在。根据ASP.NET Core Service lifetimes文件:
从单例解析范围服务/瞬态服务是危险的。处理后续请求时,可能会导致服务处于错误状态。
解决方案是:注册LoadTestCleanUpServiceRepository
和MyDbContext
如下:
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("YourConnectionStringName")));
services.AddScoped<ILoadTestCleanUpServiceRepository, LoadTestCleanUpServiceRepository>();
现在问题应该消失。