namespace netAPI.Controllers;
[ApiController]
[Route("[controller]")]
public class UserEFController : ControllerBase
{
private DataContextEF _entityFramework;
private IMapper _mapper;
public UserEFController(IConfiguration configuration)
{
_entityFramework = new DataContextEF(configuration);
_mapper = new Mapper(new MapperConfiguration(config =>
{
config.CreateMap<UserToAddDto, User>();
}));
}
[HttpGet("GetUsers")]
public IEnumerable<User> GetUsers()
{
return _entityFramework.Users.ToList<User>();
}
[HttpGet("GetSingleUser/{userId}")]
public User GetSingleUser(int userId)
{
User? user = _entityFramework.Users.FirstOrDefault(user => user.UserId == userId);
if (user != null) return user;
throw new Exception("Failed to Get User.");
}
[HttpPut]
public IActionResult EditUser(User user)
{
User? userDb = _entityFramework.Users.FirstOrDefault(u => u.UserId == user.UserId);
if (userDb != null)
{
userDb.FirstName = user.FirstName;
userDb.LastName = user.LastName;
userDb.Email = user.Email;
userDb.Gender = user.Gender;
userDb.Active = user.Active;
if (_entityFramework.SaveChanges() > 0)
{
return Ok();
}
}
throw new Exception("Failed to Update User.");
}
[HttpPost]
public IActionResult AddUser(UserToAddDto userToAdd)
{
User userDb = _mapper.Map<User>(userToAdd);
_entityFramework.Add(userDb);
if (_entityFramework.SaveChanges() > 0) return Ok("Add User Succeed.");
throw new Exception("Failed to Add User.");
}
[HttpDelete("DeleteUser/{userId}")]
public IActionResult DeleteUser(int userId)
{
User? userDb = _entityFramework.Users.FirstOrDefault(user => user.UserId == userId);
if (userDb != null)
{
_entityFramework.Users.Remove(userDb);
if (_entityFramework.SaveChanges() > 0) return Ok("Delete User Succeed.");
throw new Exception("Failed to Delete User.");
}
throw new Exception("Failed to Delete User.");
}
}
기존의 컨트롤러는 _entityFramework
를 통해 직접 데이터베이스와 상호작용한다.
이러한 방식은 하나의 기능이 한 가지 일만 처리하는 관심사 분리에 위배된다.
따라서, 우리는 컨트롤러는 사용자 요청을 처리하는 로직만 구현하고, 비즈니스 로직과 데이터 접근 로직은 리포지토리에 구현하도록 관심사를 분리한다.
namespace netAPI.Data;
public interface IUserRepository
{
public bool SaveChanges();
public void AddEntity<T>(T entityToAdd);
public IEnumerable<User> GetUsers();
public User GetSingUser(int userId);
public UserSalary GetSingleUserSalary(int userId);
public UserJobInfo GetSingleUserJobInfo(int userId);
public void RemoveEntity<T>(T entityToRemove);
}
namespace netAPI.Data;
public class UserRepository : IUserRepository
{
private DataContextEF _entityFramework;
private IMapper _mapper;
public UserRepository(IConfiguration config)
{
_entityFramework = new DataContextEF(config);
}
public bool SaveChanges()
{
return _entityFramework.SaveChanges() > 0;
}
public void AddEntity<T>(T entityToAdd)
{
if(entityToAdd != null) _entityFramework.Add(entityToAdd);
}
public IEnumerable<User> GetUsers()
{
return _entityFramework.Users.ToList();
}
public User GetSingUser(int userId)
{
User? user = _entityFramework.Users.FirstOrDefault(user => user.UserId == userId);
if (user != null) return user;
throw new Exception("Failed to get User.");
}
public UserSalary GetSingleUserSalary(int userId)
{
UserSalary? userSalary = _entityFramework.UserSalary.FirstOrDefault(user => user.UserId == userId);
if (userSalary != null) return userSalary;
throw new Exception("Failed to get UserSalary.");
}
public UserJobInfo GetSingleUserJobInfo(int userId)
{
UserJobInfo? userJobInfo = _entityFramework.UserJobInfo.FirstOrDefault(user => user.UserId == userId);
if (userJobInfo != null) return userJobInfo;
throw new Exception("Failed to get UserJobInfo.");
}
public void RemoveEntity<T>(T entityToRemove)
{
if (entityToRemove != null) _entityFramework.Remove(entityToRemove);
}
}
UserRepository
는 IUserRepository
인터페이스를 따른다.
IUserRepository
는 하위 클래스가 따라야할 메소드를 정의만 하고, 구현은 각 클래스에서 객체지향 다형성 특징을 구현한다.
리포지토리에서 데이터에 접근하기 위한 _entityFramework
를 생성하고, 필요한 메소드를 구현한다.
namespace netAPI.Controllers;
[ApiController]
[Route("[controller]")]
public class UserEFController : ControllerBase
{
private IUserRepository _userRepository;
private IMapper _mapper;
public UserEFController(IConfiguration configuration, IUserRepository userRepository)
{
_userRepository = userRepository;
_mapper = new Mapper(new MapperConfiguration(config => { config.CreateMap<UserToAddDto, User>(); }));
}
[HttpGet("User")]
public IEnumerable<User> GetUsers()
{
return _userRepository.GetUsers();
}
[HttpGet("User/{userId}")]
public User GetSingleUser(int userId)
{
return _userRepository.GetSingUser(userId);
}
[HttpPut("User")]
public IActionResult EditUser(User user)
{
User? userDb = _userRepository.GetSingUser(user.UserId);
if (userDb != null)
{
userDb.FirstName = user.FirstName;
userDb.LastName = user.LastName;
userDb.Email = user.Email;
userDb.Gender = user.Gender;
userDb.Active = user.Active;
if (_userRepository.SaveChanges()) return Ok();
}
throw new Exception("Failed to Update User.");
}
[HttpPost("User")]
public IActionResult AddUser(UserToAddDto userToAdd)
{
User userDb = _mapper.Map<User>(userToAdd);
_userRepository.AddEntity(userDb);
if (_userRepository.SaveChanges()) return Ok();
throw new Exception("Failed to Add User.");
}
[HttpDelete("User/{userId}")]
public IActionResult DeleteUser(int userId)
{
User? userDb = _userRepository.GetSingUser(userId);
if (userDb != null)
{
_userRepository.RemoveEntity(userDb);
if (_userRepository.SaveChanges()) return Ok();
throw new Exception("Failed to Delete User.");
}
throw new Exception("Failed to Delete User.");
}
[HttpGet("UserSalary/{userId}")]
public UserSalary GetSingleUserSalary(int userId)
{
return _userRepository.GetSingleUserSalary(userId);
}
[HttpPost("UserSalary")]
public IActionResult PostUserSalary(UserSalary userSalaryForAdd)
{
_userRepository.AddEntity(userSalaryForAdd);
if (_userRepository.SaveChanges()) return Ok();
throw new Exception("Failed to add UserSalary.");
}
[HttpDelete("UserSalary/{userId}")]
public IActionResult DeleteUserSalary(int userId)
{
UserSalary? userSalaryForDelete = _userRepository.GetSingleUserSalary(userId);
if (userSalaryForDelete != null)
{
_userRepository.RemoveEntity(userSalaryForDelete);
if (_userRepository.SaveChanges()) return Ok();
throw new Exception("Failed to delete UserSalary.");
}
throw new Exception("Failed to delete UserSalary.");
}
[HttpGet("UserJobInfo/{userId}")]
public UserJobInfo GetSingleUserJobInfo(int userId)
{
return _userRepository.GetSingleUserJobInfo(userId);
}
[HttpPost("UserJobInfo")]
public IActionResult PostUserJobInfo(UserJobInfo userJobInfoForAdd)
{
_userRepository.AddEntity(userJobInfoForAdd);
if (_userRepository.SaveChanges()) return Ok();
throw new Exception("Failed to add UserJobInfo.");
}
[HttpDelete("UserJobInfo/{userId}")]
public IActionResult DeleteUserJobInfo(int userId)
{
UserJobInfo? userJobInfoForDelete = _userRepository.GetSingleUserJobInfo(userId);
if (userJobInfoForDelete != null)
{
_userRepository.RemoveEntity(userJobInfoForDelete);
if (_userRepository.SaveChanges()) return Ok();
throw new Exception("Failed to delete UserJobInfo.");
}
throw new Exception("Failed to delete UserJobInfo.");
}
}
사용자 요청을 처리하는 로직을 구현하고, 해당 요청을 리포지토리로 넘겨줌으로써 데이터 변경이 발생 했는지를 파악하여 결과를 반환한다.
이로써 컨트롤러에는 데이터베이스에 접근할 수 있는 객체인 _entityFramework
가 완전히 사라지게 되었고, 해당 객체를 리포지토리 안에 숨김으로써 각각의 기능의 관심사를 완전하게 분리하였다.