Asp.net I';我是.NET Core 2.1 MVC和I'的新手;我很难理解一些事情是如何运作的

Asp.net I';我是.NET Core 2.1 MVC和I'的新手;我很难理解一些事情是如何运作的,asp.net,asp.net-core,asp.net-web-api,asp.net-core-mvc,asp.net-core-2.1,Asp.net,Asp.net Core,Asp.net Web Api,Asp.net Core Mvc,Asp.net Core 2.1,我目前正在Udemy中学习.Net Core Angular 8教程。我可以在Postman中执行get/post请求,还可以使用sqlite作为数据库查看.db文件中发布的内容,并通过db浏览器查看数据。一切似乎都很好,但如果我不能理解应用程序的某些方面发生了什么,一切都是徒劳的。如果有人能帮我回答几个问题,我将不胜感激 我的整个项目都在GitHub中: 问题1:我有以下控制器: [Route("api/[controller]")] [ApiController] p

我目前正在Udemy中学习.Net Core Angular 8教程。我可以在Postman中执行get/post请求,还可以使用sqlite作为数据库查看.db文件中发布的内容,并通过db浏览器查看数据。一切似乎都很好,但如果我不能理解应用程序的某些方面发生了什么,一切都是徒劳的。如果有人能帮我回答几个问题,我将不胜感激

我的整个项目都在GitHub中:

问题1:我有以下控制器:

    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {

        private readonly IAuthRepository _repo;
        private readonly IConfiguration _config;

        public AuthController(IAuthRepository repo, IConfiguration config)
        {
            _repo = repo;
            _config = config;
        }

        [HttpPost("register")]
        public async Task<IActionResult> Register(UserForRegisterDto userForRegisterDto)
        {
            // validate request

            userForRegisterDto.Username = userForRegisterDto.Username.ToLower();

            if (await _repo.UserExists(userForRegisterDto.Username))
                return BadRequest("User already exists");

            var userToCreate = new User
            {
                Username = userForRegisterDto.Username
            };

            var createdUser = await _repo.Register(userToCreate, userForRegisterDto.Password);

            return StatusCode(201);
        }
    }
[路由(“api/[控制器]”)]
[ApiController]
公共类AuthController:ControllerBase
{
私有只读IAuthRepository\u repo;
专用只读IConfiguration\u config;
公共AuthController(IAuthRepository repo,IConfiguration配置)
{
_回购=回购;
_config=config;
}
[HttpPost(“注册”)]
公共异步任务寄存器(UserForRegisterTo UserForRegisterTo)
{
//验证请求
userForRegisterDto.Username=userForRegisterDto.Username.ToLower();
if(wait_repo.UserExists(userForRegisterDto.Username))
返回请求(“用户已存在”);
var userToCreate=新用户
{
Username=userForRegisterDto.Username
};
var createdUser=wait _repo.Register(userToCreate,userForRegisterDto.Password);
返回状态码(201);
}
}
我知道,当客户端请求注册时,会调用register()方法,传入的用户名会将用户名从DTO设置为userForRegisterDto。在此之后,我们调用方法UserExists()来检查该用户是否存在于我们的数据库中

问题1: 当_repo只使用接口IAuthRepository时,它如何知道UserExists()方法中的逻辑?我知道IAuthRepository和类AuthRepository以某种方式链接在一起,但我在应用程序中没有看到构造函数DI发生的任何地方。我怀疑它与ConfigureServices方法下startup.cs中的这一行有关:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<DataContext>(x => x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddCors();
        services.AddScoped<IAuthRepository, AuthRepository>(); //<---- This Line
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                ValidateIssuer = false,
                ValidateAudience = false
            };
        });
    }
public void配置服务(IServiceCollection服务)
{
services.AddDbContext(x=>x.UseSqlite(Configuration.GetConnectionString(“DefaultConnection”));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddCors();
services.addScope();//{
options.TokenValidationParameters=新的TokenValidationParameters
{
ValidateSuersigningKey=true,
IssuerSigningKey=new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection(“AppSettings:Token”).Value)),
validateisuer=false,
ValidateAudience=false
};
});
}
将这两者“链接”后,可以通过AuthRepository类访问UserExists()方法:

public class AuthRepository : IAuthRepository
{
    private readonly DataContext _context;
    public AuthRepository(DataContext context)
    {
        _context = context;
    }

    public async Task<User> Login(string username, string password)
    {

    }

    private bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)
    {

    }

    public async Task<User> Register(User user, string password)
    {
        byte[] passwordHash, passwordSalt;
        CreatePasswordHash(password, out passwordHash, out passwordSalt);

        user.PasswordHash = passwordHash;
        user.PasswordSalt = passwordSalt;

        await _context.Users.AddAsync(user);
        await _context.SaveChangesAsync();

        return user;
    }

    private void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
    {


    }

    public async Task<bool> UserExists(string username)
    {
        if (await _context.Users.AnyAsync(x => x.Username == username))
            return true;

        return false;
    }
}
公共类AuthRepository:IAuthRepository
{
私有只读数据上下文_上下文;
公共AuthRepository(DataContext上下文)
{
_上下文=上下文;
}
公共异步任务登录(字符串用户名、字符串密码)
{
}
private bool VerifyPasswordHash(字符串密码,字节[]passwordHash,字节[]passwordSalt)
{
}
公共异步任务寄存器(用户,字符串密码)
{
字节[]passwordHash,passwordSalt;
CreatePasswordHash(password,out passwordHash,out passwordSalt);
user.PasswordHash=PasswordHash;
user.PasswordSalt=PasswordSalt;
wait_context.Users.AddAsync(user);
wait_context.SaveChangesAsync();
返回用户;
}
private void CreatePasswordHash(字符串密码,out byte[]passwordHash,out byte[]passwordSalt)
{
}
公共异步任务UserExists(字符串用户名)
{
if(wait_context.Users.AnyAsync(x=>x.Username==Username))
返回true;
返回false;
}
}
我一直在阅读AddScoped方法及其作用,但我不清楚情况是否如此。任何关于这是如何工作的澄清都是非常好的

问题2: 这个差不多。如果我们继续跟踪请求的路径,我们将命中AuthRepository类中的register()方法

问题2: 当我在任何地方都找不到构造函数DI的实例时,这个类如何访问DataContext\u context的属性

以下是我的其他项目文件(如果需要):

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<DataContext>(x => x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddCors();
        services.AddScoped<IAuthRepository, AuthRepository>();
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                ValidateIssuer = false,
                ValidateAudience = false
            };
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            //app.UseHsts();
        }

        //app.UseHttpsRedirection();
        app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
        app.UseAuthentication();
        app.UseMvc();
    }
}
公共类启动
{
公共启动(IConfiguration配置)
{
配置=配置;
}
公共IConfiguration配置{get;}
//此方法由运行时调用。请使用此方法将服务添加到容器中。
public void配置服务(IServiceCollection服务)
{
services.AddDbContext(x=>x.UseSqlite(Configuration.GetConnectionString(“DefaultConnection”));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddCors();
services.addScope();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(选项=>{
options.TokenValidationParameters=新的TokenValidationParameters
{
ValidateSuersigningKey=true,
IssuerSigningKey=new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection(“AppSettings:Token”).Value)),
validateisuer=false,
ValidateAudience=false
};
});
}
//此方法由运行时调用。请使用此方法配置HTTP请求管道。
公共无效配置(IAApplicationBui)
public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base (options){}
    public DbSet<Value> Values { get; set; }
    public DbSet<User> Users { get; set; }
}
services.AddDbContext<DataContext>(x => 
   x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
private readonly DataContext _context;

public AuthRepository(DataContext context)
{
    _context = context;
}