ASP.NET Core使用扩展方法IServiceCollection
来设置依赖注入,然后当需要类型时,它使用适当的方法来创建新实例:
AddTransient<T>
- 添加每次请求时再次创建的类型.AddScoped<T>
- 添加为请求范围保留的类型.AddSingleton<T>
- 在第一次请求时添加一个类型并保持它.我有类型的实现IDisposable
,如果没有处理它们会导致问题 - 在Dispose
实际调用的每个模式中?
有什么我需要添加(例如异常处理)以确保实例始终处置?
实际上我是从Blazor
和开始的EF Core
。在注册时DbContext
我陷入困境。可以通过或 进行DbContext
注册。但有什么区别呢?AddDbContext
AddDbContextFactory
builder.Services.AddDbContext<DataContext>(opt => opt.UseSqlServer("..."));\nbuilder.Services.AddDbContextFactory<DataContext>(opt => opt.UseSqlServer("..."));\n
Run Code Online (Sandbox Code Playgroud)\n从文档我得到以下信息:
\nAddDbContext
:
\n\n使用依赖注入时使用此方法...
\n
\n\nEntity Framework Core 不支持在同一 Microsoft.EntityFrameworkCore.DbContext 实例上运行多个并行操作。这包括异步查询的并行执行以及来自多个线程的任何显式并发使用。
\n
AddDbContextFactory
:
\n\n建议为 Blazor 应用程序以及依赖项注入范围与上下文生命周期不一致的其他情况注册工厂...
\n
\n\n为了方便起见,此方法还将上下文类型本身注册为作用域服务。这允许上下文实例直接从依赖项注入范围解析或由工厂创建(视情况而定)。
\n
因此,我们可以全局地说,如果程序需要DbContext
从不同的线程访问,或者同时需要注册上下文,AddDbContextFactory
因为当它被创建时(例如在控制器中),lifttime 被设置为作用域,所以我们每次得到一个新的DbContext
?
private readonly DataContext _dbContext;\n\npublic BlogController(IDbContextFactory<DataContext> dbFactory)\n{\n // Will be created as SCOPED DbContext?\n _dbContext = dbFactory.CreateDbContext();\n}\n
Run Code Online (Sandbox Code Playgroud)\n我还在这里发现了类似的问题。AddDbContext …
我现在一直在寻找有关此问题的明确答案,包括github,但仍然看不到我在这里缺少的内容:
无法从根提供者解析作用域服务' Microsoft.EntityFrameworkCore.DbContextOptions`1 [PureGateway.Data.GatewayContext] '。
在Startup.cs中:
public void ConfigureServices(IServiceCollection services)
{
//other code omitted for brevity
var connection = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<GatewayContext>(options => options.UseSqlServer(connection));
services.AddDbContextPool<GatewayContext>(options => options.UseSqlServer(connection));
services.AddScoped<IGatewayRepository, GatewayRepository>();
}
Run Code Online (Sandbox Code Playgroud)
用法:
public sealed class MatchBrokerRouteMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<MatchBrokerRouteMiddleware> _logger;
public MatchBrokerRouteMiddleware(
RequestDelegate next,
ILoggerFactory loggerFactory)
{
_next = next;
_logger = loggerFactory.CreateLogger<MatchBrokerRouteMiddleware>();
}
public async Task Invoke(HttpContext context, GatewayContext gatewayContext)
{
await _next(context);
}
Run Code Online (Sandbox Code Playgroud)
我正在使用netcore 2.2。
c# dependency-injection middleware entity-framework-core asp.net-core
我正在为现有域层构建 Blazor 服务器前端。这一层提供了各种可注入的服务来对 EF Core 存储库进行修改。为此,服务本身从(标准 Microsoft)DI 容器请求 DbContext。这适用于具有作用域 DbContext 实例的常规 MVC.NET/Razor 页面,但如文档所述,这在 Blazor 中存在问题。在 Blazor 服务器应用程序中,我们希望使用 DbContextFactory 来为操作生成短期 DbContext 实例。
在同一个应用程序中同时拥有 DbContext 和 DbContextFactory 没有问题,但我很难理解如何调整我的服务。或者,如果我什至需要?为了说明,这是当前的代码:
我的页面:
@page “/items”
@inject ItemService ItemService
// somewhere in the code
ItemService.DoOperation(…)
Run Code Online (Sandbox Code Playgroud)
我的服务
@page “/items”
@inject ItemService ItemService
// somewhere in the code
ItemService.DoOperation(…)
Run Code Online (Sandbox Code Playgroud)
启动.cs:
class ItemService
{
public ItemService(MyDbContext myDbContext)
{
…
}
public bool DoOperation(…)
{
…
_myDbContext.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
我已经根据此答案中给出的示例更改了 DbContext 的生命周期,到目前为止我还没有能够创建任何问题,但我不完全理解这里的生命周期问题。如何设计我的服务以明显的方式在 Blazor 和 MVC/Razor Pages 应用程序中运行良好?
我想注册一个作用域ICurrentUserService
,然后在 DbContext 中使用它来设置CreatedBy
每个实体的属性。我希望它具有作用域,因为它使用 currentHttpContext
从声明中获取用户 id,并且 HttpContext 根据定义具有作用域。
services.AddTransient<ICurrentUserService, CurrentUserService>();
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试将其与 DbContextFactory 一起使用时,如下所示:
services.AddDbContextFactory<MyDbContext>(options =>
options.UseSqlServer(config.ConnectionStrings.MSSQLConnection, x =>
{
x.MigrationsHistoryTable("...");
x.MigrationsAssembly("...");
}));
services.AddScoped<IMyDbContext>(provider => provider.GetRequiredService<IDbContextFactory<MyDbContext>>().CreateDbContext());
services.AddScoped<MyDbContext>(provider => provider.GetRequiredService<IDbContextFactory<MyDbContext>>().CreateDbContext());
Run Code Online (Sandbox Code Playgroud)
我收到错误
无法从根提供程序解析作用域服务“SomeNamespace.ICurrentUserService”。
我可以将其更改为 Transient,但这似乎是错误的,并且当我想模拟它并且每个类都会获得一个新实例时,这可能会成为稍后测试的问题。
我实际上不确定为什么 Scoped 在这里不起作用。DbContextFactory 已注册为 Singleton,但 Context 也被解析为 Scoped。
dependency-injection dbcontext entity-framework-core .net-core
asp.net-core ×3
c# ×3
.net-core ×2
blazor ×2
dbcontext ×2
.net-5 ×1
idisposable ×1
lifetime ×1
middleware ×1