이미 많은 사람들이 MSDN 뉴스레터를 통해 알고 있는 사실이지만, .NET Framework 3.5에 관한 백서가 한글로 번역되어 배포중이다. 닷넷 진영에서는 대단히 유명한 저술가로서, 그리고 어려운 주제에 대해 참으로 이해하기 쉽게 설명하는 데 있어서 탁월한 재주가 있는 강연자로 정평이 나있는 David Chappell이 쓴 글이 한글로 번역되었다.

.NET Framework 3.5 관련한 David Chappell의 소개글은 아래에서 다운로드 받을 수 있다. 기계 번역 후 꼼꼼히 사람이 다시 점검했기에 상당히 매끄럽고 쉬운 문장으로 번역되었다.
.NET Framework 3.5 소개
.NET Framework 3.5 WPF 소개
.NET Framework 3.5 WCF 소개
.NET Framework 3.5 WF 소개

한편, 위 David Chappell의 글을 원문으로 보길 원하는 사람들은 채펠의 홈 페이지(http://davidchappell.com/articles/white_papers.html) 를 방문하시길....

Posted by 장현춘
 DI (Dependency Injection)는 IoC (Inversion of Control), Hollywodd Principle과 거의 동의어로 사용되기도 하지만, 엄밀히 말하면 IoC 기능 가운데 Dependency를 해소시켜주는 기법을 일컫는 패턴이다. 닷넷에서 ASP.NET MVC 프레임웍을 올 상반기 중에 정식 출시할 예정인데, 이로써 기존 ASP.NET Page 방식이나 이를 기반으로한 Web Client Software Factory (WCSF) 이외에, 개발자가 사용할 수 있는 또 다른 개발 방식을 제공하게 된다. DI 컨테이너라고 칭해지는 것들은 이와 같은 프리젠테이션 구현 기법과 연동하여 비지니스 로직을 구현하는 과정에서 생성되는 객체들의 라이프사이클을 관리해주고 이들 사이의 Dependency를 IoC 방식으로 해결해주는 프레임웍을 의미한다. 이러한 DI 컨테이너들은 프리젠테이션 티어의 구현 방식과 상관없이 선택적으로 적용할 수 있으며 반드시 비지니스 티어에서만 사용되는 것이 아니고 애플리케이션의 전 티어에서 필요시 객체 라이프 사이클 관리를 맡길 수 있다.
 DI 컨테이너로는 이전 포스트에서 밝혔듯이, Windsor Container, StructureMap, Spring.NET, Object Builder가 있으며 오늘 소개할 Unity Container가 있다. Object Builder는 마이크로소프트의 P&P (Patterns & Practices) 팀에서 만든 것으로 현재 Enterprise Library, CAB (Composite Application Block), WCSF 등 마이크로소프트의 각종 Application Block 에 쓰이고 있다. 하지만, 애초 일반 개발자를 위해 만든 것이 아니고 이처럼 각종 Application Block 내부에서 사용하기 위해 만든 것이기 때문에 개발자를 위한 API가 정리되지 않았고 이를 이용하기 위해서는 너무 많은 클래스들을 알아야 하는 어려움이 있었다. 하여 P&P 팀에서는 Enterprise Library v4 개발 계획을 발표하면서 Object Builder 후속으로 새로운 DI Container를 제공하겠다고 밝힌 바 있으며, 이것에 대한 약속으로 약 열흘 전에 Unity Application Block 2월 CTP를 공개하였다. Unity에 대한 자세한 정보는 CodePlex (http://codeplex.com/unity) 에서 찾을 수 있다.
 Unity는 기본적으로 Object Builder를 기반으로 작성된 Lightweight한 DI 컨테이너로써, 사용 편의성 증대를 위해 DI 기능을 쉽게 익힐 수 있는 Attribute 기반으로 제공하고 있다. Injection 기법으로는 일반적으로 사용되는 Contructor Injection, Property Injection, Method call Injection을 모두 제공한다. 또한 복잡한 계층 구조로 된 객체들의 생성도 아주 간편하게 처리할 수 있고, dependency를 런타임시에 제공할 수도 있고 XML 파일을 통해 제공할 수 도 있다. 아울러 Unity 컨테이너 자체를 필요에 따라서는 클라이언트 모듈이 ASP.NET의 Session이나 Application 에 저장하여 재사용할 수도 있다.  자세한 설명이나 샘플 등은 CodePlex 참고하기 바란다.

사용자 삽입 이미지

Patterns & Practices

Posted by 장현춘

ASP.NET MVC 프레임웍의 정식 출시를 앞두고 이의 구현과 연관된, 혹은 이와 연동하는 프레임웍에 대한 논의가 활성화되고 있다. 또한 단순 프레임웍 차원이 아니라 관련 패턴 설명서, 참조 구현, 아키텍처 관련 설명, 툴 지원 등등을 묶어 마이크로소프트 P&P (Pattners and Practices) 팀에서 Software Factory라는 이름으로 시리즈를 내고 있다. 하여 ASP.NET MVC와 연동 혹은 경쟁하게 될 Software Factory로는 Web Client Software Factory (WCSF, http://www.codeplex.com/websf)가 있으며, 이미 블로그 스피어 상에는 둘 사이의 차이점 및 연동 방안 등에 대한 글들이 올라오고 있다. 기존 ASP.NET이 MVC 패턴 중 Page Controller를 구현한 것과는 달리, ASP.NET MVC는 이름에서 말하고 있듯이 MVC 패턴 중에서 Front Controller 패턴을 구현하고 있다. 아울러 WCSF는 잘 알려진 바 대로 Application Controller 패턴을 구현하고 있다. 
Page Controller나 Front Controller에 대해서는 P&P 책자에서도 상세히 설명되고 있고, 이를 기반으로 한 2년 전에 필자가 웹 캐스트를 찍은 것이 마이크로소프트 홈페이지 e-learning 싸이트에 여전히 올라가 있으니 관심있는 사람들은 이를 참고하면 좋을 듯 하다. 이 시간에는 Application Controller에 대해 살펴보기로 하고 이를 통해 다음 기회에 작성할 WCSF에 대한 이해를 높이는 기회가 되었으면 한다.

Application Controller가 웹 애플리케이션의 프리젠테이션 티어에서 주로 사용하는 것이나 특성상 꼭 그런 것은 아니다. 여기서는 웹 프리젠테이션 티어에서 사용되는 것을 통해 Application Controller가 여타 다른 Controller 패턴 들과 연동하는 모습을 살펴보기로 한다. 일반적으로 웹 프리젠테이션 티어는 Page Controller나 Front Controller 패턴을 구현한 프레임웍을 통해 구성되며, 대부분의 경우 이러한 Controller만으로 족하다. 하지만 UI 로직이 복잡해져서 사용자에게 전달될 화면이 특정 순서로 제공되어야 하거나, 혹은 사용자 세션의 현재 상태 혹은 시스템의 현재 상태에 따라서, 즉 상태 머신 (State Machine)처럼, 상태 기반으로 제공되는 화면이 달라야 하는 경우에는 Page Controller나 Front Controller를 통해 구현하기에는 벅차다. 즉, Page Controller 기반이라면 여러 Controller들에게 똑같은 혹은 비슷한 로직이 중복될 것이며, Front Controller로 구현한다면 Controller 자체가 너무 비대해져서 시스템의 규모가 커지거나 향후 유지보수 시에 융통성이 떨어지게 된다. 또한 이러한 Controller 들은 웹 프로토콜에 직접 노출되기 때문에 테스트에 취약하다.

 
Application Controller는 이러한 Controller 뒤에 위치하여 사용자의 요구에 부합되는 비지니스 로직 모듈을 찾아 수행하고 결과에 맞는 화면을 제공하는 역할을 한다. 즉, 일반적으로 Front Controller가 담당하는 역할 중에서 웹 인터페이스 부분은 여전히 Front Controller에 맡기고, 웹과 한 발 떨어져 일반 클래스로 위에서 언급한 애플리케이션 흐름을 제어하는 역할을 한다. 따라서 간단한 웹 애플리케이션의 경우 Application Controller 없이 Front Controller만으로 족하나, 시스템의 복잡성, 특히 화면 관련 흐름 제어 로직이 복잡해질 경우 이를 별도의 모듈, 즉, Application Controller로 떼어내는 것이 바람직하다. 이렇게 되면 Application Controller 자체는 웹 특성을 많은 부분 없앨 수 있어 단위 테스트 등의 테스팅 프레임웍을 이용하는 것이 한결 쉬워진다.
일부 문서에서는 Application Controller를 별도 패턴으로 인정하지 않고 Front Controller의 Helper로 기술하는 경우도 있다. 닷넷의 경우 WCSF가 Application Controller를 구현한 것으로 여겨지고, 자바의 경우 Struts가 대표적이다. Struts의 경우 초반에는 ActionServlet이라는 Front Controller 만으로 구현되어 있었는데, 버전이 올라가면서 ActionServlet이외에 RequestProcessor를 두어 웹과 인터페이스하는 부분을 제외한 모든 일, 즉, Filter Chain 적용하기, 맵핑 정보 확인, 사용자 요구에 맞는 비지니스 모듈 찾기 (주로 Command 패턴으로 구현), 비지니스 로직 수행 결과에 따른 뷰 찾기 등등을 모두 RequestProcessor에 일임한다. ActionServlet은 Front Controller이고 RequestProcessor는 Application Controller이다.
  
위 그림에서 Command Factory나 View Factory 등은 모두 생략하였으며, 궁극적으로 Application Controller가 애플리케이션 흐름 제어에 필요한 클래스를 찾아 수행하고 결과를 반환하는 역할을 함을 보여준다. 이름이 의미하듯 Application Controller이며, 이 Controller에 비지니스 도메인과 관련된 로직을 담는 것은 바람직하다고 여져진다. 즉, 도메인과 상관없이 애플리케이션 차원에서 필요한 로직들, 화면 전환이나 이를 위해 필요한 각종 판단 근거가 되는 정보 들, Mapper 등등이 여기에 관여된다. 애플리케이션 로직과 도메인 관련 비지니스 로직의 구분이 모호할 경우, 마틴 파울러는 한번으로 끝나는 것은 Applicatin Controller 로직에 포함하고 여러 곳에서 자주 쓰이는 로직은 비지니스 모듈쪽으로 빼는 것이 바람직하다는 의견을 제시한다. Application Controller에 대해서는 이미 마틴 파울러의 웹 싸이트 및 그의 저서 Patterns of Enterprise Application Architecture (P of EAA) 에서 상세히 설명하고 있다. P of EAA에서는 약간 추상적인 논의가 많아서 재미없어 하는 분이 있다면, 자바 관련 서적이긴 하지만, Core J2EE Patterns를 참고해도 좋다. 

Posted by 장현춘

자바와 닷넷에서의 쓰레드 모델을 살펴보자

자바의 경우,

쓰레드 생성은...
java.lang.Thead를 상속받아 클래스를 정의하거나 java.lang.Runnable을 구현하는 클래스를 정의하며 클래스내에는 public void run() {} 메소드가 정의되어야 한다. 명시적으로 클래스를 만들지 않고 anonymous class 형태로 쓰레드를 생성할 수 있다.
new Thread() { public void run() { ………… } }.start(); 
혹은
new Thread(new Runnable() { public void run() { ……………} }).start();
로 쓰레드를 생성하고 바로 실행시킨다.

쓰레드 동기화는...
synchronized라는 키워드가 존재하여 쓰레드 간 동기화 작업을 지원한다. 사용방법은 원하는 블록을 지정하여 synchronized로 지정할 수도 있고, 메소드의 modifier로 사용되어 메소드 전체에 대해 flag 방식으로 지정되어 좀 더 효율적인 방법을 제공하고 있다.(j2se 1.4 기준) Lock으로는 객체lock과 클래스lock을 지원하며, 객체lock의 경우 synchronized(this) {} 와 같이 지정하고 이 경우 호출되는 객체가 객체lock으로 지정되며, 원하는 객체를 lock으로 지정할 수도 있다. synchronized(youTheObject) {}와 같이 사용한다.
클래스lock의 경우 synchronized(MyClass.class) {} 와 같이 지정하거나, static 메소드의 modifier로 synchronized가 사용된 경우로서, 이 경우 MyClass.class를 지칭하는 java.lang.Class.class 객체의 인스턴스가 클래스lock으로 지정된다. 클래스를 지칭하는 Class 인스턴스는 JVM내에 유일하게 관리된다.
객체lock과 클래스lock은 동시에 사용가능하다. 즉, 객체lock을 필요로 하는 메소드와 클래스lock을 필요로하는 메소드는 동시에 두 쓰레드로부터 호출될 수 있다. (이점이 닷넷과 다르다 !!!)
j2se 5.0 부터 concurrent programming을 지원하기 위해 java.util.concurrent.* 가 추가되었다. 이는 자바 concurrent 프로그래밍의 대가인 Doug Lea의 작업 산출물이 추가된 것으로 보인다.

닷넷의 경우,

쓰레드 생성은…
쓰레드 풀과 delegate을 써서 이루어지는데, System.Threading.ThreadPool.QueueUserWorkItem 메소드를 통해 이루어지며 파라미터로 원하는 메소드의 delegate을 넘겨줌으로써 쓰레드 방식으로 동작하게 된다. Thread pool manager는 넘겨받은 delegate을 queue에 쌓아놓고 가용한 쓰레드가 있을 경우 이를 할당하여 메소드를 실행시킨다.
닷넷 프레임웍에도 System.Threading.Thread라는 클래스가 있지만 sealed되어 개발자가 상속받을 수 없다. 하지만 직접 new 연산자를 써서 쓰레드를 생성할 수 있다. 이때 Thread의 contructor로 전달되는 파라미터는 실행을 원하는 메소드를 지칭하는 delegate이다. 즉,
new Thread(new ThreadStart(ThreadProc)).Start();     // ThreadStart는 delegate, ThreadProc은 메소드임
와 같이 실행시킨다. (상속을 제외하고 자바와 유사하다…..)
Thread.ThreadState property를 통해 상태를 알 수 있다.
New Thread() --> Unstarted 상태
Thread.Start() --> Running 상태 (OS의 ready list에 올리는 것일 뿐, 바로 실행되는 것은 아니다.)
Thread.Suspend() --> Suspended 상태.
Thread.Resume() --> Suspended에서 Running 상태로
Thread.Sleep() --> WaitSleepJoin 상태
Suspended 상태는 Thread.Resume()에 의해서만 깨어날 수 있으나,
WaitSleepJoin 상태는 지정한 시간이 경과하거나, lock을 잃어버리거나, Thread.Interrupt()가 호출되거나할 경우 깨어난다. System.Threading.ThreadInterruuptedException 처리가 요망된다. (자바와 같다.)
(자바에서는 Thread.stop(), Thread.suspend(), Thread.resume() 모두 deprecated되었는데, 이유는 이러한 것들이 쓰레드의 상태를 깨뜨릴 수 있는 불안전한 메소드들이기 때문이다.)
쓰레드 우선순위는 5개다 : Highest, AboveNormal, Normal, BelowNormal, Lowest  (자바는 1 ~10)
우선순위는 Thread.Priority property를 통해 알 수 있다.
Thread.Abort()를 통해 쓰레드를 종료시키는데, Abort가 호출되었다고 쓰레드가 종료되었다고 볼수 없다. Abort가 호출되면 ThreadAbortException이 발생하는데, 이 Exception은 특별하여 catch블럭 끝에서 자동적으로 다시 ThreadAbortException을 발생시킨다. Catch 블록 안에서 Thread.ResetAbort()를 호출하여 Abort()를 무력화 시킬수도 있기 때문에 Thread.Join()을 호출하여 정말 쓰레드가 죽었는지 확인해야 한다. Thread.Join()은 쓰레드가 죽기 전에는 리턴하지 않는 blocking call이다.

쓰레드 동기화는...
VB.NET의 경우 SyncLock이라는 키워드가 있고, C#에는 lock이라는 키워드가 있어서, 자바의 synchronized와 동일한 역할을 한다.
Lock 객체가 객체 레벨과 클래스 레벨과 분리되어 있는 것은 자바와 동일하나 내부적으로 자바와 같은 방식으로 관리하는지는 알 수 없다.(아직까지…^^)
닷네의 경우에는 자바 보다 다양한 방식으로 thread synchronization을 지원하는데
첫째, attribute 기반 thread synchronization은 System.Runtime.Remoting.Contexts.SynchronizationAttribute를 클래스 attribute로 지정하고 ContextBoundObject를 상속받아 클래스를 작성하면 된다. 이경우 해당 클래스의 모든 메소드에 접근할때마다 lock객체를 얻어야하는 오버헤드가 발생한다.
둘째, C#의 lock 키워드 (VB.NET의 SyncLock)를 사용하여 제공한다. 이 경우 원하는 메소드 내에 블록을 지정하여 해당 블록에서만 lock 객체를 얻도록 할 수 있다. 내부적으로 컴파일러가 System.Threading.Monitor 클래스를 통해 synchronization을 제공한다. Monitor.Enter… Monitor.Exit
셋째, System.Threading.Monitor 객체를 직접 코드에서 다루면서 synchronization을 제공할 수 있다.
닷넷에서 특이한 점은 일단 한 쓰레드에 의해 특정 클래스의 클래스lock이 얻어진 경우, 그 클래스의 모든 인스턴스에 대한 접근이 block된다. 즉, 클래스lock은 모든 객체lock을 잡지 못하도록 만든다. (정말 ?? 이점이 특히 자바와 다르다. !!!!)

자바와 닷넷에서 쓰레드 생성 코드를 비교하면 너무나 유사하다. 자바에는 Anonymous class라는 개념이 있는 반면, 닷넷에는 Anonymous Method 라는 개념이 있다.

* 자바의 경우
new Thread(new Runnable() {
  public void run()
  {
     System.out.println("babo");
  }
}).start();

* 닷넷의 경우
new Thread(delegate() {
   Console.WriteLine("babo");
}).Start();

Posted by 장현춘

마이크로소프트는 이전 포스트에서 언급했듯이  SaaS (Software as a Service)에 대한 좀 더 포괄적인 접근을 하고 있으며 이를 Software + Services (이하 S+S) 라는 개념으로 접근하고 있다.  S+S 관련하여 아키텍처 관점에서 각종 아티클이나 논의 및 LitwareHR은 샘플 애플리케이션을 제공하는 마이크로소프트의 공식적인 페이지가 개편되었다. 예전에 비해 좀 더 정리가 된 모습인데, SaaS에 대해서 참여 주체들의 관심 영역 혹은 역할에 맞게 정리를 한 것을 볼 수 있다. 즉, S+S에 대해 서비스 제공자 입장에서 접근하는지, S+S 애플리케이션을 호스팅하는 입장에서 접근하는지, S+S를 소비자하는 입장에서 바라보는 지, 혹은 S+S 애플리케이션에 마켓플레이스를 제공하여 활성화를 제공하는지 (즉, 장터를 제공하는 지)에 따라 분류하고 있어 자신의 목적에 맞는 내용을 쉽게 접근할 수 있다. 관심있는 사람들은 아래 싸이트를 방문하길 ...
 
 MSDN SaaS 아키텍처 페이지 바로가기

개편한지 며칠 되지 않았으며 방문자들의 피드백을 간절히 바라고 있다.

Posted by 장현춘