[ C# .NET ] 컨트롤러와 리포지토리 분해

박제현·2024년 6월 11일
0

.NET

목록 보기
7/7

기존 컨트롤러

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 를 통해 직접 데이터베이스와 상호작용한다.

이러한 방식은 하나의 기능이 한 가지 일만 처리하는 관심사 분리에 위배된다.

따라서, 우리는 컨트롤러는 사용자 요청을 처리하는 로직만 구현하고, 비즈니스 로직과 데이터 접근 로직은 리포지토리에 구현하도록 관심사를 분리한다.

리포지토리

interface IUserRepository

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);
}

class UserRepository

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);
    }
}

UserRepositoryIUserRepository 인터페이스를 따른다.

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 가 완전히 사라지게 되었고, 해당 객체를 리포지토리 안에 숨김으로써 각각의 기능의 관심사를 완전하게 분리하였다.

profile
닷넷 새싹

0개의 댓글

관련 채용 정보