C# 如何使用接口在API控制器中作为助手类或处理程序单独编写业务逻辑
我正在使用实体框架开发.net RESTful WebAPI,其中包含带操作的API控制器 它将自动生成控制器,因此我需要在控制器(C# 如何使用接口在API控制器中作为助手类或处理程序单独编写业务逻辑,c#,entity-framework,asp.net-web-api,C#,Entity Framework,Asp.net Web Api,我正在使用实体框架开发.net RESTful WebAPI,其中包含带操作的API控制器 它将自动生成控制器,因此我需要在控制器(EmployeeDetailController)中将业务逻辑写入helper(EmployeeDetailHandler)类,并与接口(IEEmployeeDetailHandler)连接 因此需要将Dbcontext连接到helper类(EmployeeDetailHandler),而无需依赖控制器来使用xunit测试单元测试 如何编写处理程序类和控制器类 这是
EmployeeDetailController
)中将业务逻辑写入helper(EmployeeDetailHandler
)类,并与接口(IEEmployeeDetailHandler
)连接
因此需要将Dbcontext
连接到helper类(EmployeeDetailHandler
),而无需依赖控制器来使用xunit测试单元测试
如何编写处理程序类和控制器类
这是我的控制器(带有操作的API控制器,使用实体框架)
我需要通过将接口连接到控制器类,在helper类上分别编写该类中的逻辑
[Route("api/[controller]")]
[ApiController]
public class EmployeeDetailController : ControllerBase
{
private readonly AuthenticationContext _context;
public EmployeeDetailController(AuthenticationContext context)
{
_context = context;
}
// GET: api/EmployeeDetail
[HttpGet]
public IEnumerable<EmployeeDetail> GetEmployeeDetails()
{
return _context.EmployeeDetails;
}
// GET: api/EmployeeDetail/5
[HttpGet("{id}")]
public async Task<IActionResult> GetEmployeeDetail([FromRoute] int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var employeeDetail = await _context.EmployeeDetails.FindAsync(id);
if (employeeDetail == null)
{
return NotFound();
}
return Ok(employeeDetail);
}
// PUT: api/EmployeeDetail/5
[HttpPut("{id}")]
public async Task<IActionResult> PutEmployeeDetail([FromRoute] int id, [FromBody] EmployeeDetail employeeDetail)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != employeeDetail.EId)
{
return BadRequest();
}
_context.Entry(employeeDetail).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!EmployeeDetailExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/EmployeeDetail
[HttpPost]
public async Task<IActionResult> PostEmployeeDetail([FromBody] EmployeeDetail employeeDetail)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.EmployeeDetails.Add(employeeDetail);
await _context.SaveChangesAsync();
return CreatedAtAction("GetEmployeeDetail", new { id = employeeDetail.EId }, employeeDetail);
}
// DELETE: api/EmployeeDetail/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteEmployeeDetail([FromRoute] int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var employeeDetail = await _context.EmployeeDetails.FindAsync(id);
if (employeeDetail == null)
{
return NotFound();
}
_context.EmployeeDetails.Remove(employeeDetail);
await _context.SaveChangesAsync();
return Ok(employeeDetail);
}
private bool EmployeeDetailExists(int id)
{
return _context.EmployeeDetails.Any(e => e.EId == id);
}
}
Expect是与接口相关的处理程序类(service/Hepler)。单元测试是针对可以单独测试的少量代码 忘掉控制器,忘掉DbContext,专注于业务逻辑 您的控制器应该是薄层,执行模型验证并将数据传递给业务层,仅此而已。因此,你甚至不需要看它们 因此,对业务逻辑进行单元测试。使用集成测试覆盖每个端点,以确定正确和不正确的模型等 使用诸如Postman之类的工具或任何其他允许这样做的工具来协调集成测试
您展示的代码根本不适合单元测试。DBContext和单元测试不在同一句话中
public class AuthenticationContext : IdentityDbContext
{
public AuthenticationContext(DbContextOptions options):base(options {}
public DbSet<ApplicationUser> ApplicationUsers { get; set; }
public DbSet<EmployeeDetail> EmployeeDetails { get; set; }
}
public class EmployeeDetail
{
[Key]
public int EId { get; set; }
[Required]
[Column(TypeName = "Nvarchar(100)")]
public string EmployeeName { get; set; }
[Required]
[Column(TypeName = "Nvarchar(10)")]
public string PhoneNo { get; set; }
[Required]
[Column(TypeName = "Nvarchar(10)")]
public string BDay { get; set; }
[Required]
[Column(TypeName = "Nvarchar(10)")]
public string Nic { get; set; }
}