Midnight Peach Quick Start Part II

Midnight Peach 2012. 5. 23. 23:21

본 포스트는 Midnight Peach 3.x 버전의 빠른 설명서입니다.

본 포스트는 두 개의 파트로 이루어져 있습니다.

파트 I에서는 서비스 레이어(WCF)를 두지 않는 형태(즉, 클라이언트에서 DB에 바로 붙는 경우)를 다루고, 파트 II에서는 서비스 레이어를 포함하는 구조에 대해서 각각 설명합니다.

 

0. DB 스키마 준비

파트 I과 동일한 스키마를 사용하니, 파트I을 참조하십시오.

 

1. 솔루션의 생성

MP를 실행한 후 Tool –> Generate Solution을 실행합니다.

image

이번에는 LINQ2SQL Use Service를 선택합니다.

생성된 솔루션을 비주얼 스튜디오에서 엽니다.

image

4개의 프로젝트가 생성이 되는데 각 역할은 다음과 같습니다.

  • Test Console : 간단한 테스트용(단위 테스트와 상관 없음) 코드를 작성하기 위한 콘솔 프로젝트입니다.
  • Data : 데이터 엑세스 레이어입니다. DBML 파일이 위치하고 있으며, 파트1의 Biz 프로젝트와 유사한 역할을 합니다.
  • Service : Data 프로젝트에서 만든 데이터 엑세스 메서드(MP가 생성한 코드 + 사용자가 만든 코드)를 래퍼하는 WCF 메서드가 있습니다.
  • Biz : Service 메서드를 호출하는 래퍼 메서드가 있습니다. Data와 Service 프로젝트와는 달리 클라이언트 측에 위치합니다.

아래 그림은 각 프로젝트 간의 실행 흐름입니다.

image

푸른색은 클라이언트에서 실행되는 코드, 붉은색은 (WCF가 실행되는) 서버에서 실행되는 코드입니다.

아주 중요한 그림이니 좀 있다 한번 더 말씀 드리겠습니다.

 

2. DBML의 작성

역시 파트I과 동일합니다.

 

3. 데이터 레이어 코드 생성

서비스를 사용하는 솔루션에서는 MP가 두 단계의 코드를 생성합니다.

첫번째 단계는 DBML 파일을 소스로 하여 데이터 엑세스 코드를 생성하는데, 파트I에서는 이 기능 만을 사용합니다.

두번째 단계는 Data 프로젝트를 빌드한 결과인 DLL (여기서는 Memopad.Data.DLL)을 소스로 하여, 이 DLL에 있는 메서드 들에 대한 래퍼 메서드를 생성하는 단계입니다.

먼저 첫번째 단계부터 진행을 하겠습니다.

MP에서 위에서 생성된 Memopad.mp 파일을 열고, Generate –> Data를 실행하여 코드를 생성합니다.

솔루션탐색기에서 Show All Files 버튼을 클릭하여 MP가 생성한 파일을 표시합니다.

image

Generated 폴더에서 오른쪽 버튼을 클릭한 후 Include In Project를 선택합니다.

image

두번째 단계를 진행하기 위해 먼저 커스텀 메서드를 만들어 보겠습니다.

Entities 폴더에 Memo 클래스를 추가하고 아래와 같이 코드를 작성합니다.

image

WCF 서비스를 통과해야 하므로 DataMember 특성을 추가하여야 합니다.

다음에는 Data 폴더에 MemoData 클래스를 추가하고 아래와 같이 코드를 작성합니다.

image_thumb[27]

ForService 특성이 지정되어있는데, 이 특성은 MP로 하여금 이 메서드에 대한 서비스 레이어 코드를 생성하라는 것을 지시하는 역할을 합니다.

이제 비주얼 스튜디오에서 빌드를 하여 Memopad.Data.DLL을 생성합니다.

 

4. 서비스 레이어의 생성

다시 MP에서 Generate –> Service 를 실행하여, 서비스와 비지니스 코드를 생성합니다.

코드를 생성하고 나면 아래와 같은 메시지 박스가 나오는데, 이는 현재 MP의 해결하지 못한 버그입니다.

image

[2012.6.1 업데이트]

위 버그는 3.0.15 버전에서 수정되었습니다.

아래 그림과 같이 Biz 프로젝트에서 MP가 생성된 코드들을 추가합니다.

image

 

5. 솔루션 구성 테스트

솔루션이 적절히 구성되었는지 테스트를 할 차례입니다.

먼저 Memopad.Biz 프로젝트에 ServiceFactory 클래스를 추가하고 아래와 같이 코드를 작성합니다.

image

WCF 서비스가 배포된 주소를 지정하여야 하는데, 위 그림은 비주얼 스튜디오에 내장된 개발 서버를 사용하는 경우의 예입니다.

예에서는 54179 포트를 사용하는데 물론 사용자마다 다를 것입니다.

Memopad.Service 프로젝트의 속성 중 Web 탭에 있는 정보를 참고하여 적절한 포트번호를 지정하면 되겠습니다.

image 

MP와 관련은 없지만, 비주얼 스튜디오의 내장된 개발 서버 대신 IIS Express를 사용하실 것을 적극 추천합니다.

Memopad.Service 프로젝트의 web.config 파일을 열어 DB 연결문자열을 적절히 수정합니다.

image

TestConsole 프로젝트의 Program.cs 파일에 아래 코드를 작성하여 솔루션이 제대로 구성되었는지 확인합니다.

image

TestConsole 프로젝트를 시작 프로젝트로 지정한 후 실행해서 예외가 발생하지 않고 정수 값이 출력되면 정상입니다.

 

6. 실행 흐름

이해를 돕기 위해 여기까지의 과정을 메서드의 실행흐름을 중심으로 정리해 보겠습니다.

클라이언트(즉 위에서는 TestConsole)에서 Bizrepository.Memo.GetCount 메서드를 호출하면 MemoBizBase 클래스의 GetCount 메서드가 호출됩니다.

image

이 메서드는 사용자 지정 비니지스 로직을 추가하기 위해 가상으로 지정되어 있습니다. (잠시 후에 좀 더 이야기를 해보겠습니다.)

그리고 ServiceFactory.GetService 메서드를 호출하여 IMemopadDataService ServiceContract 특성이 지정된 인터페이스를 구현한 객체를 생성합니다.

image

CreateBinding 메서드와 GetAddress 메서드는 각각 내부적으로 부분 메서드인 CreateBindingCore 와 GetAddressCore 를 호출하는데, 이 부분 메서드들을 사용자가 설정하면 각각 바인딩과 서비스의 주소를 재지정할 수 있습니다.

위에서 GetAddressCore 메서드를 구현한 것이 바로 주소를 지정하는 단계였습니다.

IMemopadDataService 인터페이스에는 데이터 엑세스 레이어의 메서드 중 ForService 특성이 붙은 메서드들이 모두 포함되어 있습니다.

image

위 그림에서 Memo_GetByCategoryName 은 사용자가 작성한 커스텀 메서드이고, Memo_GetByPK 는 MP가 자동 생성한 메서드 중 하나 입니다.

다시 Bizrepository.Memo.GetCount 메서드로 돌아가서, 서비스 객체를 만들고 나면 이를 이용해서 서비스 메서드를 호출합니다.

image

이 서비스 메서드 역시 MP가 생성하는데, 아래와 같습니다.

image

단순히 MemoData 클래스를 만든 후 GetCount() 메서드를 호출합니다.

MP가 만드는 기본 템플릿에는 서비스 메서드에 대한 인증 관련 코드가 빠져 있습니다.
실무에서는 인증 토큰이나 아이디와 패스워드를 전달하는 방법 등으로 인증을 해야할텐데, 이 경우에는 MP의 템플릿(확장자가 mp인 파일)을 수정하여야 합니다.
참고로 MP의 템플릿을 수정하기 위해서는 MP가 사용하는 매크로 언어인 MPML의 EBNF를 알아야 하는데, 이는 MP에서 볼 수 있습니다.
데이터 레이어를 만드는 EBNF에 대해서는 예전 포스트에서 설명한 적인 있는데, 서비스 레이어에 관해서는 아직 작성이 되어 있지 않습니다.

사실 MemoData 클래스에는 GetCount 메서드가 없습니다.

GetCount 메서드는 MemoData 의 부모 클래스인 EntityData<T> 에 저장되어 있습니다.

이 GetCount 메서드는 내부적으로 몇 개의 오버로드를 거치게 되는데 최종적으로 실행되는 메서드는 아래와 같습니다.

image

DbContext 객체를 생성하는 일을 하는 DataContextFacotry.Create 메서드를 제외하면, 모두 닷넷 프레임웍이 기본 제공하는 코드입니다.

그래서 MP가 생성한 코드는 여기가 마지막입니다.

 

6. 커스텀 비지니스 로직의 추가

커스텀 비지니스 로직을 추가하기 위해서는 각 엔터티의 BizBase 클래스를 상속 받는 클래스를 만들고 해당 메서드를 오버라이드 하여야 합니다.

사실 MP에는 이 BizBase 클래스를 상속 받는 클래스들이 이미 만들어져 있습니다.

image

이미 클래스가 만들어져 있으니, 동일한 이름으로 부분 클래스를 Memopad.Biz 프로젝트에 추가하고 아래와 같이 비지니스 로직을 추가합니다.

image

image

위 예에서는 단순히 파라미터의 유효성을 검사하는 코드를 추가하였습니다.

여기서 유심히 볼 부분은 바로 부모인 MemoBizBase 의 GetByCategoryName  메서드를 오버라이드하고, 커스텀 비지니스 로직 호출 전/후에 부모 클래스의 해당 메서드를 다시 호출하는 패턴이 되겠습니다.

 

7. 맺음말

MP는 단순한 코드가 아니라 프레임웍을 생성하는 것을 목표로 하고 있습니다.

그래서 비주얼 스튜디오의 솔루션 전체를 생성하는 기능을 제공하는 것인데, 이 솔루션에는 N-티어 아키텍쳐의 각 레이어에 해당하는 프로젝트들이 포함되어 있으며, 각 프로젝트에는 해당 프로젝트가 필요로 하는 어셈블리가 이미 참조되어 있고, 필수적으로 필요한 코드가 포함되어 있습니다.

물론 MP가 생성하는 솔루션의 아키텍쳐가 실무의 요구사항을 모두 만족하지는 않을 것입니다.

다만 MP는 N-티어 아키텍쳐와 LINQ에 익숙하지 않은 개발자에게, 솔루션을 어떻게 구성하고 어떤 코드를 어떤 레이어에 작성해야 하는가와 같은 문제에 대한 가이드 역할을 하고자 합니다.

 

온라인에서 글쓰기를 하면서 ‘지면관계상’ 이라는 말을 쓸 수는 없지만, MP를 설명하는 이 포스트에는 정말 많은 부분이 누락되어 있습니다.

관용적인 표현이 아니라, 정말로 열의 하나도 설명을 다 하지 못했습니다.

물론 MP를 만든 제가 친절하게 설명을 하는 것도 중요하지만, 결국에는 스스로 연구하고 습득하는 수 밖에 없을 것 같습니다.

이왕 MP를 공개까지 하였으니, 책임감을 느낌과 함께 가급적이면 개발자들의 공동체에 도움이 되었으면 합니다.

MP의 소스 코드 역시 곧 공개하겠습니다.

2012.6.4 업데이트
Codeplex 를 통해 소스가 공개되었습니다. 이 포스트를 참조하십시오.

MP 자체가 전 세계 개발자 공동체에서 제가 직간접적으로 전수 받은 지식으로 만들어진 것이니 당연한 일이겠지요.

: