问题描述
我应该如何将我的 MyDbContext
注入我的数据库服务层 MyService
?
How am I supposed to inject my MyDbContext
into my database service layer MyService
?
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));
services.AddMvc();
}
MyDbContext.cs
public partial class MyDbContext : DbContext
{
public virtual DbSet<User> User { get; set; }
public MyDbContext(DbContextOptions<MyDbContext> options)
:base(options)
{
}
}
appsettings.json
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=MyServer;Database=MyDatabase;user id=MyUser;password=MyPassword;"
}
}
MyService.cs
public class MyService
{
public User GetUser(string username)
{
// Should i remove this call and get the reference from the injection somehow?
MyDbContext db_context = new MyDbContext(optionsBuilder.Options);
using (db_context)
{
var users = from u in db_context.User where u.WindowsLogin == username select u;
if (users.Count() == 1)
{
return users.First();
}
return null;
}
}
}
在我的 GetUser
方法中,我知道我应该在这里使用注入的 MyDbContext
但我不太确定如何获取它.我错过了哪一块拼图?
In my GetUser
method, I know I am supposed to be using my injected MyDbContext
here but I am not quite sure how to fetch it. Which piece of the puzzle am I missing?
推荐答案
您不必自己包含dbcontext,ASP.NET核心依赖注入服务会为您完成.
You don't have to include the dbcontext yourself, ASP.NET core dependency injection service will do this for you.
您只需在启动类中声明您的服务和数据库上下文,并将您需要的 dbcontext 放入服务的构造函数中:
You have just to declare your services and your database context in your startup class, and put the dbcontext you need in your service's constructor :
Startup.cs(你必须选择你想要的服务生命周期,这里是一个范围服务,每个请求一次):
Startup.cs (your have to choose the service lifetime you want, here it's a scoped service, once per request):
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));
services.AddMvc();
services.AddScoped<IMyService, MyService>();
}
您的服务等级:
public class MyService : IMyService
{
private readonly MyDbContext _context;
public MyService(MyDbContext ctx){
_context = ctx;
}
public User GetUser(string username)
{
var users = from u in _context.User where u.WindowsLogin == username select u;
if (users.Count() == 1)
{
return users.First();
}
return null;
}
}
public interface IMyService
{
User GetUser(string username);
}
在您的控制器中,您必须以相同的方式声明您需要使用的服务(或数据库上下文):
In your controller, you have to declare the services (or the database context) you need to use in the same way :
public class TestController : Controller
{
private readonly IMyService _myService;
public TestController(IMyService serv)
{
_myService = serv;
}
public IActionResult Test()
{
return _myService.MyMethod(); // No need to instanciate your service here
}
}
关于控制器的注意事项:您不必像使用数据库上下文或服务那样将它们添加到启动类中.只需实现它们的构造函数.
Note about the controller : you don't have to add them in your startup class like you do with your database context or your services. Just implement their constructor.
如果您需要有关 .NET Core 依赖注入的更多信息,官方文档非常清晰且非常完整:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection
If you need more information about the .NET Core depencency injection, the official documentation is clear and very complete : https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection
注意:在 startup.cs 中,AddScoped 行是一个选项.您可以选择您想要的服务寿命.您可以选择不同的生命周期:
NB: In the startup.cs, the AddScoped line is an option. Your can choose the lifetime you want for your service. There is the different lifetimes you can choose :
瞬态
每次请求时都会创建瞬态生命周期服务.此生命周期最适合轻量级、无状态的服务.
Transient lifetime services are created each time they are requested. This lifetime works best for lightweight, stateless services.
作用域
范围内的生命周期服务为每个请求创建一次.
Scoped lifetime services are created once per request.
单例
单例生命周期服务在首次创建时创建请求(或者如果您指定实例,则在运行 ConfigureServices 时那里),然后每个后续请求都将使用相同的实例.
Singleton lifetime services are created the first time they are requested (or when ConfigureServices is run if you specify an instance there) and then every subsequent request will use the same instance.
以上摘自:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection
注意:这不是这里的问题,但您的 GetUser 数据查询对我来说有点奇怪.如果您的 count()==1 目标是检查用户的唯一性,那么好的方法是在数据库中添加唯一性约束.如果 count()==1 目标是检查您是否有数据以避免对象空引用异常,您可以使用 .FirstOrDefault(),它将为您管理.您可以简化此方法:
public User GetUser(string username) => (from u in _context.User where u.WindowsLogin == username select u).FirstOrDefault();
这篇关于将 DbContext 注入服务层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!