ASP.NET 模型中的核心 DI
ASP.NET CORE DI in model
我正在尝试了解 DI 在新 ASP Core 中的工作原理。通过教程,我使其适用于控制器,但无法使其适用于模型。例如,我有一个 AuthController,我向它注入了数据库上下文,但是现在,由于我有更多的控制器,共享同一个模型,即 Authentication
,我想向模型注入上下文本身。这是我的一些代码:
来自Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddDbContext<GameContext>(options => options.UseSqlServer(@"Data Source=DESKTOP-USER\SQLEXPRESS;Initial Catalog=Db7;Integrated Security=True;Connect Timeout=30;"));
}
这是我在控制器中使用它的方式:
[Route("api/[controller]")]
public class AuthController : Controller
{
public GameContext db;
public AuthController(GameContext context)
{
db = context;
}
[HttpPost]
[Route("login")]
public LoginResponseModel Login([FromBody] LoginModel user) //public Models.VM.LoginModel Login([FromBody] Models.VM.LoginModel user)
{
//query user
var detectedUser = db.Users.FirstOrDefault(u => u.Email == user.Email && u.Password == HelperClass.Md5(user.Password);
如果我从控制器中删除上下文部分,并将其移动到模型中,我将无法再次实例化它,因为构造函数需要一个参数(会自动注入?)
public class Authentication
{
public GameContext db;
public Authentication(GameContext context)
{
db = context;
}
...
如何从模型访问数据库?
编辑:
这就是我的身份验证 class 的样子(根据解决方案,构造函数可能看起来不同):
public class Authentication
{
public GameContext db;
public Authentication(GameContext context)
{
db = context;
}
public LoginResponseModel Login(LoginModel user)
{
//query user
var detectedUser = db.Users.FirstOrDefault(u => u.Email == user.Email && u.Password == HelperClass.Md5(user.Password));
下面是我想通过控制器使用此模型的方式:
[Route("api/[controller]")]
public class AuthController : Controller
{
public AuthController(GameContext context)
{
}
// POST api/login
[HttpPost]
[Route("login")]
public LoginResponseModel Login([FromBody] LoginModel user) //public Models.VM.LoginModel Login([FromBody] Models.VM.LoginModel user)
{
Authentication auth = new Authentication(); //throws error since no parameter passed
return auth.Login(user);
}
您基本上是在为其他控制器创建可重用的服务。
首先创建所需功能的抽象。
public interface IAuthenticationService {
LoginResponseModel Login(LoginModel user);
}
并让实现继承自该接口
public class Authentication : IAuthenticationService {
private readonly GameContext db;
public Authentication(GameContext context) {
db = context;
}
public LoginResponseModel Login(LoginModel user) {
//query user
var detectedUser = db.Users.FirstOrDefault(u => u.Email == user.Email && u.Password == HelperClass.Md5(user.Password));
//...other code that creates and returns an instance of LoginResponseModel
}
}
有了它,您需要向服务集合注册接口,以便 DI 框架在看到该接口时知道要注入什么。
来源:Asp.Net Core Fundamentals: Dependency Injection
public void ConfigureServices(IServiceCollection services) {
...
services.AddDbContext<GameContext>(options => options.UseSqlServer(@"Data Source=DESKTOP-USER\SQLEXPRESS;Initial Catalog=Db7;Integrated Security=True;Connect Timeout=30;"));
// Add application services.
services.AddTransient<IAuthenticationService, Authentication>();
}
现在任何需要访问该服务的控制器都可以将其注入到其构造函数中
[Route("api/[controller]")]
public class AuthController : Controller {
private readonly IAuthenticationService auth;
public AuthController(IAuthenticationService auth) {
this.auth = auth;
}
// POST api/login
[HttpPost]
[Route("login")]
public LoginResponseModel Login([FromBody] LoginModel user) {
return auth.Login(user);
}
}
DI 框架将处理创建和注入服务的所有繁重工作。您现在不必自己创建实例。
我正在尝试了解 DI 在新 ASP Core 中的工作原理。通过教程,我使其适用于控制器,但无法使其适用于模型。例如,我有一个 AuthController,我向它注入了数据库上下文,但是现在,由于我有更多的控制器,共享同一个模型,即 Authentication
,我想向模型注入上下文本身。这是我的一些代码:
来自Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddDbContext<GameContext>(options => options.UseSqlServer(@"Data Source=DESKTOP-USER\SQLEXPRESS;Initial Catalog=Db7;Integrated Security=True;Connect Timeout=30;"));
}
这是我在控制器中使用它的方式:
[Route("api/[controller]")]
public class AuthController : Controller
{
public GameContext db;
public AuthController(GameContext context)
{
db = context;
}
[HttpPost]
[Route("login")]
public LoginResponseModel Login([FromBody] LoginModel user) //public Models.VM.LoginModel Login([FromBody] Models.VM.LoginModel user)
{
//query user
var detectedUser = db.Users.FirstOrDefault(u => u.Email == user.Email && u.Password == HelperClass.Md5(user.Password);
如果我从控制器中删除上下文部分,并将其移动到模型中,我将无法再次实例化它,因为构造函数需要一个参数(会自动注入?)
public class Authentication
{
public GameContext db;
public Authentication(GameContext context)
{
db = context;
}
...
如何从模型访问数据库?
编辑:
这就是我的身份验证 class 的样子(根据解决方案,构造函数可能看起来不同):
public class Authentication
{
public GameContext db;
public Authentication(GameContext context)
{
db = context;
}
public LoginResponseModel Login(LoginModel user)
{
//query user
var detectedUser = db.Users.FirstOrDefault(u => u.Email == user.Email && u.Password == HelperClass.Md5(user.Password));
下面是我想通过控制器使用此模型的方式:
[Route("api/[controller]")]
public class AuthController : Controller
{
public AuthController(GameContext context)
{
}
// POST api/login
[HttpPost]
[Route("login")]
public LoginResponseModel Login([FromBody] LoginModel user) //public Models.VM.LoginModel Login([FromBody] Models.VM.LoginModel user)
{
Authentication auth = new Authentication(); //throws error since no parameter passed
return auth.Login(user);
}
您基本上是在为其他控制器创建可重用的服务。
首先创建所需功能的抽象。
public interface IAuthenticationService {
LoginResponseModel Login(LoginModel user);
}
并让实现继承自该接口
public class Authentication : IAuthenticationService {
private readonly GameContext db;
public Authentication(GameContext context) {
db = context;
}
public LoginResponseModel Login(LoginModel user) {
//query user
var detectedUser = db.Users.FirstOrDefault(u => u.Email == user.Email && u.Password == HelperClass.Md5(user.Password));
//...other code that creates and returns an instance of LoginResponseModel
}
}
有了它,您需要向服务集合注册接口,以便 DI 框架在看到该接口时知道要注入什么。
来源:Asp.Net Core Fundamentals: Dependency Injection
public void ConfigureServices(IServiceCollection services) {
...
services.AddDbContext<GameContext>(options => options.UseSqlServer(@"Data Source=DESKTOP-USER\SQLEXPRESS;Initial Catalog=Db7;Integrated Security=True;Connect Timeout=30;"));
// Add application services.
services.AddTransient<IAuthenticationService, Authentication>();
}
现在任何需要访问该服务的控制器都可以将其注入到其构造函数中
[Route("api/[controller]")]
public class AuthController : Controller {
private readonly IAuthenticationService auth;
public AuthController(IAuthenticationService auth) {
this.auth = auth;
}
// POST api/login
[HttpPost]
[Route("login")]
public LoginResponseModel Login([FromBody] LoginModel user) {
return auth.Login(user);
}
}
DI 框架将处理创建和注入服务的所有繁重工作。您现在不必自己创建实例。