如何将 DbContext 注入 ASP.NET 核心中的存储库构造函数
How to inject DbContext into repository constructor in ASP.NET core
我正在编写我的第一个 ASP.NET Core Web API 并且正在尝试弄清楚如何将我的 DbContext 对象注入到我的存储库构造函数中。我遵循了此 tutorial 的 EF 部分,其中 DbContext 通过 services.AddDbContext<DbContext>
注册到服务集合,services.GetRequiredService<DbContext>()
用于初始化数据库值。
public class Startup
{
public IConfiguration Configuration {
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<IItemRepository, ItemRepository>();
services.AddSingleton<IUserRepository, UserRepository>();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
});
services.AddDbContext<RAFYCContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
}
public class Program
{
public static void Main(string[] args)
{
//CreateWebHostBuilder(args).Build().Run();
IWebHost host = CreateWebHostBuilder(args).Build();
using (IServiceScope scope = host.Services.CreateScope())
{
IServiceProvider services = scope.ServiceProvider;
try
{
RAFYCContext context = services.GetRequiredService<RAFYCContext>();
DbInitializer.Initialize(context);
}
catch (Exception ex)
{
ILogger logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred while seeding the database.");
}
}
host.Run();
}
}
我能够将 DbContext 注入控制器,然后调用存储库方法将其分配给 UserRepository:
public class UserController : ControllerBase
{
IUserRepository _userRepo;
public UserController(IUserRepository userRepo, RAFYCContext context)
{
_userRepo = userRepo;
_userRepo.SetDbContext(context);
}
}
public class UserRepository : IUserRepository
{
public RAFYCContext _context;
public UserRepository() { }
public void SetDbContext(RAFYCContext context)
{
this._context = context;
}
}
这可行,但是我想将 DbContext 注入到我的存储库的构造函数中,而不是在实例化后在 Controller 构造函数中分配它,如下所示:
[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
IUserRepository _userRepo;
public UserController(IUserRepository userRepo)
{
_userRepo = userRepo;
}
}
public class UserRepository : IUserRepository
{
RAFYCContext _context;
public UserRepository(RAFYCContext context)
{
_context = context;
}
}
使用此代码我得到以下错误:
InvalidOperationException: Cannot consume scoped service
'RAFYC.MobileAppService.Models.RAFYCContext' from singleton
'RAFYC.MobileAppService.Repositories.IUserRepository'
有人知道 ASP.NET Core (2.2) 是否可行吗?
AddDbContext
默认添加一个 DbContext
范围,这会导致单例存储库出现问题。
It's dangerous to resolve a scoped service from a singleton. It may cause the service to have incorrect state when processing subsequent requests.
引用Dependency injection in ASP.NET Core: Service lifetimes
如果可能的话,我建议添加存储库。
services.AddScoped<IItemRepository, ItemRepository>();
services.AddScoped<IUserRepository, UserRepository>();
我正在编写我的第一个 ASP.NET Core Web API 并且正在尝试弄清楚如何将我的 DbContext 对象注入到我的存储库构造函数中。我遵循了此 tutorial 的 EF 部分,其中 DbContext 通过 services.AddDbContext<DbContext>
注册到服务集合,services.GetRequiredService<DbContext>()
用于初始化数据库值。
public class Startup
{
public IConfiguration Configuration {
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<IItemRepository, ItemRepository>();
services.AddSingleton<IUserRepository, UserRepository>();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
});
services.AddDbContext<RAFYCContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
}
public class Program
{
public static void Main(string[] args)
{
//CreateWebHostBuilder(args).Build().Run();
IWebHost host = CreateWebHostBuilder(args).Build();
using (IServiceScope scope = host.Services.CreateScope())
{
IServiceProvider services = scope.ServiceProvider;
try
{
RAFYCContext context = services.GetRequiredService<RAFYCContext>();
DbInitializer.Initialize(context);
}
catch (Exception ex)
{
ILogger logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred while seeding the database.");
}
}
host.Run();
}
}
我能够将 DbContext 注入控制器,然后调用存储库方法将其分配给 UserRepository:
public class UserController : ControllerBase
{
IUserRepository _userRepo;
public UserController(IUserRepository userRepo, RAFYCContext context)
{
_userRepo = userRepo;
_userRepo.SetDbContext(context);
}
}
public class UserRepository : IUserRepository
{
public RAFYCContext _context;
public UserRepository() { }
public void SetDbContext(RAFYCContext context)
{
this._context = context;
}
}
这可行,但是我想将 DbContext 注入到我的存储库的构造函数中,而不是在实例化后在 Controller 构造函数中分配它,如下所示:
[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
IUserRepository _userRepo;
public UserController(IUserRepository userRepo)
{
_userRepo = userRepo;
}
}
public class UserRepository : IUserRepository
{
RAFYCContext _context;
public UserRepository(RAFYCContext context)
{
_context = context;
}
}
使用此代码我得到以下错误:
InvalidOperationException: Cannot consume scoped service 'RAFYC.MobileAppService.Models.RAFYCContext' from singleton 'RAFYC.MobileAppService.Repositories.IUserRepository'
有人知道 ASP.NET Core (2.2) 是否可行吗?
AddDbContext
默认添加一个 DbContext
范围,这会导致单例存储库出现问题。
It's dangerous to resolve a scoped service from a singleton. It may cause the service to have incorrect state when processing subsequent requests.
引用Dependency injection in ASP.NET Core: Service lifetimes
如果可能的话,我建议添加存储库。
services.AddScoped<IItemRepository, ItemRepository>();
services.AddScoped<IUserRepository, UserRepository>();