Tuesday, December 7, 2010

관리자용 서비스를 위해 ASP.NET MVC에서 Areas(영역) 이용

ASP.NET MVC를 이용한 서비스 모델 개발시 관리자 영역을 구분할때 좀 애매모한 상황에서 고민하게 된다.

컨트롤러에서 각 액션메서드마다 필터로 접근 제한이 가능하기 때문에, 전통적인 방식과 같이 따로 Admin라는 폴더를 구성하고 그 안에 관리자용 서비스를 몰아둘 필요가 없어졌다. 혹자는 심지어 이제 그러한 관리자 페이지에 대한 패러다임을 바꿀필요가 있다고 까지 얘기 하고 있다.

단순한 게시판 서비스와 같이 서비스 모델이 상당히 간단하고 명확할 경우 기존의 컨트롤러에서 관리자용 액션메서드를 구현해서 사용하면 된다. 그리고 규모가 큰 서비스의 경우 기존의 Controllers, Models, Views 폴더에 적절히 하위 폴더를 생성하고 서비스를 구성할 수도 있다. 그리고 라우터만 잘 설정하면 URI 구조로도 영역을 구분지어둘 수 있다.

그런데, 쇼핑몰이나 복합적인 서비스들(비록 각 서비스 규모가 작을지라도)로 구성된 서비스를 구성할 경우 몇가지 고민이 들게된다.

“MVC 필터를 사용하여 접근 제한 하는건 알겠는데… 그래도 뭔가 찜찜하다!”
“사용자가 조회하는 회원 목록과 관리자가 조회하는 회원 목록은 각기 사용하는 데이터소스가 다르다!”
“Member 컨트롤러 List 액션메서드에 if문 사용하기는 거시기 하고… 그렇다고 회원 목록을 가져오는건데, 사용자는 List액션메서드를 사용하고, 관리자는 뭐… List2 액션메서드 쓰까?”
“액션메서드에 일일이 Authorize 필터를 달아줘야 하다니! 그냥 컨트롤러에 Authorize 달면 좋잖아!”
“여차해서 서비스 한 부분이 뚝! 떨어져 별도의 서비스로 독립되어 서비스 해야한다면… 이거…뭐…!!” 

“아~~~ MVC에서 관리자 페이지 구성하려니 여전히 찜찜하네…”

익숙하지 않은 패턴때문일수도 있지만, 사실 규모가 커질경우 이러한 문제가 현실이 되어버린다. 쇼핑몰에서 관리자용 서비스를 따로 때여 별도의 도메인으로 서비스를 하게 될 경우, 각 컨트롤러의 관리자용 액션메서드들을 따로 추출해서 재구성해야하는 문제가 생긴다. (도메인 모델은 통상 별도의 프로젝트로 분리하는것으로 본다.)

이렇게 서비스의 구분을 필요로 하는 경우 ASP.NET MVC에서 제공하는 Areas(영역)를 활용할 수 있다.

서비스에 영역을 추가할 경우 Areas 폴더가 생성되고 하위에 지정한 이름의 새 영역 폴더가 만들어진다. 그리고 그 하위에는 별도의 MVC 고유의 폴더인 Controllers, Models 그리고 Views폴더가 생성된것을 확인할 수 있다.

이렇게 추가된 영역은 global.asax에 보면 AreaRegistration.RegisterAllAreas();에 의해 서비스 시작시 등록된다.

새로 만든 영역의 접근은 기본적인 라우트규칙에서 /[영역이름]/{controller}/{action}/{id} 와 같은 구조를 가진다. 따라서 새로운 영역으로 이름이 Admin이라는 영역을 생성했다면, 회원 목록을 조회할때 통상… http://[도메인]/Admin/Member 와 같이 접근이 가능하다. 물론 사용자가 회원 목록을 조회하고자 한다면 http://[도메인]/Member 와 같이 접근하면 된다.

이렇게 영역을 구분할 경우, 각 영역별 컨트롤러의 네임스페이스가 서로 다르게 되므로…
같은 이름의 컨트롤러를 각 영역별로 작성이 가능해진다. 따라서 물리적으로 서비스별 컨트롤러를 구분할 수 있다.

물론 모델도 영역별로 구분가능하다. 도메인 모델을 별도의 프로젝트로 빌드한다 해도, ViewModels 패턴을 적용한 모델의 경우 각 영역별 모델에 위치시켜두고 관리할 수도 있겠다. 

굳이 영역을 사용하지 않아도 이러한 구분은 네임스페이스 구분과 적절한 하위폴더 관리로도 가능하겠지만, 컨트롤러, 모델 그리고 뷰가 각각 관리되어 서비스 단위별로 관리해야할 필요가 큰 경우 이러한 영역을 활용하면 도움이 되지 않을까 싶다.

Notes