ASP.NET Core Repository 패턴
ASP.NET Core 리포지토리 패턴 사용 절차
ASP.NET Core 6.0에서 Repository 패턴을 사용하는 절차는 다음과 같습니다.
- 인터페이스 정의
- Repository 인터페이스를 정의합니다.
- 예를 들어, Product 테이블의 CRUD(Create, Read, Update, Delete) 작업을 수행하는 경우, IProductRepository 인터페이스를 정의합니다.
- 구현 클래스 작성
- Repository 인터페이스를 구현하는 클래스를 작성합니다.
- 예를 들어, Product 테이블의 CRUD 작업을 수행하는 경우, ProductRepository 클래스를 작성합니다.
- ProductRepository 클래스는 Entity Framework Core를 사용하여 데이터베이스와 상호 작용합니다.
- 이 클래스는 DbContext 클래스를 상속받아서 DbContext 객체를 생성하고,
DbSet<T>
속성을 사용하여 테이블에 접근합니다.
- 서비스 등록
- DI(Dependency Injection) 컨테이너에 Repository 인터페이스와 구현 클래스를 등록합니다.
- ConfigureServices 메서드에서 다음과 같이 등록합니다.
services.AddScoped<IProductRepository, ProductRepository>();
- 컨트롤러에서 사용
- 컨트롤러에서 Repository 인터페이스를 생성자 주입을 통해 사용합니다.
- 예를 들어, ProductController에서 IProductRepository를 사용하는 경우, 다음과 같이 작성합니다.
private readonly IProductRepository _productRepository;
public ProductController(IProductRepository productRepository)
{
_productRepository = productRepository;
}
- Repository 사용
- 컨트롤러에서 Repository 인터페이스의 메서드를 호출하여 데이터베이스와 상호 작용합니다.
- 예를 들어, ProductController에서 Get 메서드를 사용하는 경우, 다음과 같이 작성합니다.
public IActionResult Get()
{
var products = _productRepository.GetProducts();
return Ok(products);
}
위와 같이 Repository 패턴을 사용하면, 데이터베이스와의 상호 작용을 캡슐화하여 코드의 가독성과 유지보수성을 높일 수 있습니다. 또한, 테스트 용이성도 향상됩니다.
리포지토리 패턴 코드 예시
아래는 Product.cs 예시 코드입니다.
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime CreatedDate { get; set; }
}
- 인터페이스 정의
public interface IProductRepository
{
IEnumerable<Product> GetProducts();
Product GetProductById(int id);
void AddProduct(Product product);
void UpdateProduct(Product product);
void DeleteProduct(int id);
}
- 구현 클래스 작성
public class ProductRepository : IProductRepository
{
private readonly ApplicationDbContext _dbContext;
public ProductRepository(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
public IEnumerable<Product> GetProducts()
{
return _dbContext.Products.ToList();
}
public Product GetProductById(int id)
{
return _dbContext.Products.FirstOrDefault(p => p.Id == id);
}
public void AddProduct(Product product)
{
_dbContext.Products.Add(product);
_dbContext.SaveChanges();
}
public void UpdateProduct(Product product)
{
_dbContext.Products.Update(product);
_dbContext.SaveChanges();
}
public void DeleteProduct(int id)
{
var product = _dbContext.Products.FirstOrDefault(p => p.Id == id);
if (product != null)
{
_dbContext.Products.Remove(product);
_dbContext.SaveChanges();
}
}
}
- 서비스 등록
services.AddScoped<IProductRepository, ProductRepository>();
- 컨트롤러에서 사용
private readonly IProductRepository _productRepository;
public ProductController(IProductRepository productRepository)
{
_productRepository = productRepository;
}
- Repository 사용
public IActionResult Get()
{
var products = _productRepository.GetProducts();
return Ok(products);
}
- Web API에서 사용
아래는 ProductController.cs 예시 코드입니다.
[ApiController]
[Route("api/[controller]")]
public class ProductController : ControllerBase
{
private readonly IProductRepository _productRepository;
public ProductController(IProductRepository productRepository)
{
_productRepository = productRepository;
}
[HttpGet]
public IActionResult Get()
{
var products = _productRepository.GetProducts();
return Ok(products);
}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
var product = _productRepository.GetProductById(id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
[HttpPost]
public IActionResult Post(Product product)
{
if (product == null)
{
return BadRequest();
}
_productRepository.AddProduct(product);
return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
}
[HttpPut("{id}")]
public IActionResult Put(int id, Product product)
{
if (product == null || id != product.Id)
{
return BadRequest();
}
var existingProduct = _productRepository.GetProductById(id);
if (existingProduct == null)
{
return NotFound();
}
_productRepository.UpdateProduct(product);
return NoContent();
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
var existingProduct = _productRepository.GetProductById(id);
if (existingProduct == null)
{
return NotFound();
}
_productRepository.DeleteProduct(id);
return NoContent();
}
}
- MVC에서 사용
아래는 ProductController.cs 예시 코드입니다.
public class ProductController : Controller
{
private readonly IProductRepository _productRepository;
public ProductController(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public IActionResult Index()
{
var products = _productRepository.GetProducts();
return View(products);
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Product product)
{
if (ModelState.IsValid)
{
_productRepository.AddProduct(product);
return RedirectToAction("Index");
}
return View(product);
}
public IActionResult Edit(int id)
{
var product = _productRepository.GetProductById(id);
if (product == null)
{
return NotFound();
}
return View(product);
}
[HttpPost]
public IActionResult Edit(int id, Product product)
{
if (id != product.Id)
{
return BadRequest();
}
if (ModelState.IsValid)
{
_productRepository.UpdateProduct(product);
return RedirectToAction("Index");
}
return View(product);
}
public IActionResult Delete(int id)
{
var product = _productRepository.GetProductById(id);
if (product == null)
{
return NotFound();
}
return View(product);
}
[HttpPost, ActionName("Delete")]
public IActionResult DeleteConfirmed(int id)
{
_productRepository.DeleteProduct(id);
return RedirectToAction("Index");
}
}
- jQuery로 CRUD 구현
아래는 jQuery를 사용하여 Web API 컨트롤러의 CRUD를 수행하는 예시 코드입니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Product CRUD Example</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<table id="productsTable">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
<th>Created Date</th>
<th></th>
</tr>
</thead>
<tbody></tbody>
</table>
<div>
<h2>Add Product</h2>
<form id="addProductForm">
<label for="name">Name:</label>
<input type="text" id="name" name="name" /><br />
<label for="price">Price:</label>
<input type="number" id="price" name="price" /><br />
<button type="submit">Add Product</button>
</form>
</div>
<div>
<h2>Edit Product</h2>
<form id="editProductForm">
<input type="hidden" id="editProductId" name="id" />
<label for="editName">Name:</label>
<input type="text" id="editName" name="name" /><br />
<label for="editPrice">Price:</label>
<input type="number" id="editPrice" name="price" /><br />
<button type="submit">Update Product</button>
</form>
</div>
<script>
$(document).ready(function () {
// Get products and populate table
$.get("/api/Product", function (data) {
var productsTable = $("#productsTable tbody");
$.each(data, function (index, product) {
var row = "<tr>" +
"<td>" + product.id + "</td>" +
"<td>" + product.name + "</td>" +
"<td>" + product.price + "</td>" +
"<td>" + product.createdDate + "</td>" +
"<td>" +
"<button class='editButton' data-id='" + product.id + "'>Edit</button> " +
"<button class='deleteButton' data-id='" + product.id + "'>Delete</button>" +
"</td>" +
"</tr>";
productsTable.append(row);
});
});
// Add new product
$("#addProductForm").submit(function (event) {
event.preventDefault();
var name = $("#name").val();
var price = $("#price").val();
var product = {
name: name,
price: price
};
$.post("/api/Product", product, function (data) {
location.reload();
});
});
// Edit product
$(document).on("click", ".editButton", function () {
var productId = $(this).data("id");
$.get("/api/Product/" + productId, function (product) {
$("#editProductId").val(product.id);
$("#editName").val(product.name);
$("#editPrice").val(product.price);
});
});
$("#editProductForm").submit(function (event) {
event.preventDefault();
var id = $("#editProductId").val();
var name = $("#editName").val();
var price = $("#editPrice").val();
var product = {
id: id,
name: name,
price: price
};
$.ajax({
url: "/api/Product/" + id,
type: "PUT",
data: product,
success: function (result) {
location.reload();
}
});
});
// Delete product
$(document).on("click", ".deleteButton", function () {
var productId = $(this).data("id");
$.ajax({
url: "/api/Product/" + productId,
type: "DELETE",
success: function (result) {
location.reload();
}
});
});
});
</script>
</body>
</html>
위 코드는 jQuery를 사용하여 웹 페이지에서 GET, POST, PUT, DELETE 요청을 수행하고 있습니다. GET 요청으로 API 엔드포인트 /api/Product에서 제품 목록을 가져온 다음, $.each 메소드를 사용하여 각 제품을 표시하는 HTML 테이블을 생성합니다. 이 페이지에서 추가, 수정 및 삭제 버튼을 사용하여 각 작업을 수행할 수 있습니다.
"Add Product" 버튼을 클릭하면, $.post 메소드를 사용하여 API 엔드포인트 /api/Product로 POST 요청을 보냅니다. "Edit" 버튼을 클릭하면, 해당 제품의 ID를 사용하여 API 엔드포인트 /api/Product/{id}로 GET 요청을 보내서 제품 정보를 가져옵니다. 가져온 정보를 사용하여 "Edit Product" 양식을 채웁니다. 수정 양식에서 "Update Product" 버튼을 클릭하면, API 엔드포인트 /api/Product/{id}로 PUT 요청을 보냅니다. "Delete" 버튼을 클릭하면, 해당 제품의 ID를 사용하여 API 엔드포인트 /api/Product/{id}로 DELETE 요청을 보냅니다. 위 코드는 간단한 예제이며, 실제 개발에서는 유효성 검사 및 보안과 같은 추가 기능이 필요합니다.