模型中的 ASP.NET CORE DI

Kis*_*ány 5 c# dependency-injection asp.net-core-1.0

我试图了解 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;"));
}
Run Code Online (Sandbox Code Playgroud)

这是我在控制器中使用它的方法:

[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);
Run Code Online (Sandbox Code Playgroud)

如果我从控制器中删除上下文部分,并将其移动到模型中,我将无法再次实例化它,因为构造函数需要一个参数(将自动注入?)

public class Authentication
{
    public GameContext db;

    public Authentication(GameContext context)
    {
        db = context;
    }
    ...
Run Code Online (Sandbox Code Playgroud)

我如何从模型访问数据库?

编辑:

这就是我的 Authentication 类的样子(构造函数可能根据解决方案看起来有所不同):

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));
Run Code Online (Sandbox Code Playgroud)

这是我想如何从控制器使用这个模型:

[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);
    }
Run Code Online (Sandbox Code Playgroud)

Nko*_*osi 3

您基本上为其他控制器提供了可重用的服务。

首先创建您想要的功能的抽象。

public interface IAuthenticationService {
    LoginResponseModel Login(LoginModel user);
}
Run Code Online (Sandbox Code Playgroud)

并让实现继承这个接口

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
    }
}
Run Code Online (Sandbox Code Playgroud)

完成后,您需要向服务集合注册接口,以便 DI 框架在看到该接口时知道要注入什么。

来源:Asp.Net Core 基础知识:依赖注入

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>();
}
Run Code Online (Sandbox Code Playgroud)

现在任何需要访问该服务的控制器都可以将其注入到其构造函数中

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

DI 框架将处理创建和注入服务的所有繁重工作。您现在不必自己创建实例。