将DbContext注入服务层 [英] Injecting DbContext into service layer

查看:715
本文介绍了将DbContext注入服务层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该如何将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/zh-cn/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.

单人

Singleton生命周期服务是首次创建的 请求(如果指定实例,则在运行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注入服务层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆