'c#'에 해당되는 글 184건

  1. 2014.08.17 .NET에서의 String과 Null Character에 대한 이야기
  2. 2013.10.25 NUnit Runner를 대신하는 간편한 Self Runner 구현하기
  3. 2013.10.20 Windows Azure Linux Virtual Machine과 docker를 이용한 Linux 기반의 C# 개발 환경 구축
  4. 2013.10.18 Practical Code Writing Tips in C#
  5. 2013.07.16 NuGet 패키지 관리자를 이용한 TDD 초기 환경 구축하기
  6. 2013.02.03 C#과 VB.NET의 using 구문을 간편하게 쓰는 방법
  7. 2013.01.02 AutoResetEvent? ManualResetEvent? 뭐가 다를까?
  8. 2012.11.01 2012년 11월 Windows Azure 관련 소식 종합
  9. 2012.10.29 Mono 3.0 출시
  10. 2012.10.26 ClickOnce의 문서화되지 않은 비관리 API 활용하기
  11. 2012.10.08 Photoshop 없이 PSD 파일의 레이어 추출하기
  12. 2012.09.15 Visual Studio 2012 Express 출시 (1)
  13. 2012.07.28 [Tip] MySQL의 password Hash 함수와 동일한 .NET 구현
  14. 2012.07.13 Windows Azure Media Service 활용하기
  15. 2012.02.10 Phalanger와 PHP의 차이점들
  16. 2012.02.08 PHP x C# x VB.NET = ASP.NET
  17. 2011.12.26 유용한 멀티 타기팅 팩: Portable Library Tools (1)
  18. 2011.04.14 Visual Studio 2010 Service Pack 1에 대한 모든 것
  19. 2011.04.14 Visual Studio 2010 Service Pack 1에 대한 모든 것
  20. 2011.04.02 응용프로그램 가상화 종결자 - roozz
  21. 2011.03.29 A Lap around cloud computing – 1인 1근두운 시대
  22. 2011.03.25 [세미나] Visual Studio 공식 팀 - Your Smarter Visual Studio 2010
  23. 2011.03.17 Microsoft TechDays 2011 Spring - N-스크린 시대의 IT 전문가를 위한 온라인 컨퍼런스 (2)
  24. 2011.03.02 CASEQRCODE powered by Windows Azure Platform
  25. 2011.02.27 A Lap around cloud computing – 지금이 여러분의 이력서를 새로 쓸 시간
  26. 2011.02.25 Windows Azure Virtual Lab으로 쉽고 빠르게 클라우드 개발 실습하기
  27. 2011.02.24 CODEPARTY 2011년 2월 / 세션 1 발표 자료 공유합니다.
  28. 2011.02.17 DevForce 프레임워크의 Windows Azure 마이그레이션 DEMO 동영상
  29. 2011.02.17 실전 Cloud App 분석 세미나 발표 자료 공유합니다. (2)
  30. 2011.02.17 {CODE PARTY} 세미나 개발자들을 위한 클라우드 개발
Windows + .NET2014. 8. 17. 09:36

.NET은 문자열을 다루는 데 있어서 C, C++, 혹은 파스칼과 비슷한 듯 다른 면이 있습니다. 그리고 이번 아티클에서는 사소하지만 큰 오류를 내포하게 될 가능성이 있는 부분을 잠시 소개하려고 합니다.

http://msdn.microsoft.com/ko-kr/library/ms228362.aspx 에서는 .NET의 String에 대해 이렇게 소개하고 있습니다.

 

 


문자열은 값이 텍스트인 String 형식의 개체입니다. 내부적으로 텍스트는 Char 개체의 순차적 읽기 전용 컬렉션으로 저장됩니다. C# 문자열 끝에는 null 종결 문자가 없습니다. 따라서 C# 문자열은 포함된 null 문자(‘\0′)를 제한 없이 포함할 수 있습니다. 문자열의 Length 속성은 유니코드 문자의 수가 아니라 포함된 Char 개체의 수를 나타냅니다. 문자열에서 개별 유니코드 코드 포인트에 액세스하려면 StringInfo 개체를 사용합니다.

굵게 강조 표시한 부분의 내용에 오늘 아티클의 핵심 내용이 모두 들어있습니다. 하지만 꼼꼼하게 기억해두지 않으면 허술하게 다루어질 가능성도 있는 부분이라고 생각합니다.

위의 내용을 상기하면서, 아래의 코드들이 각각 어떻게 실행될지 예상해보면 흥미롭습니다.
string a = "'abc'".Replace('\'', default(char));
Console.WriteLine("a: {0} (Length: {1})", a, a.Length);
string b = "'abc'".Replace('\'', Char.MinValue);
Console.WriteLine("b: {0} (Length: {1})", b, b.Length);
string c = "'abc'".Replace('\'', (char)0);
Console.WriteLine("c: {0} (Length: {1})", c, c.Length);
string d = "'abc'".Replace('\'', '\0');
Console.WriteLine("d: {0} (Length: {1})", d, d.Length);


 

 

Replace로 한 글자만 제거하고 싶어서 위와 같은 코드를 작성하기 쉬운데, 위의 결과에서 원래 의도는 ‘abc’ 라는 다섯 글자를 abc라는 세 글자로 만드는 것이지만, 실제로는 여전히 다섯 글자가 됩니다. 그런데 여기서 한 가지 더 중요한 것은, Trim() 메서드가 앞 뒤로 붙는 null character를 제거해 주지는 않는다는 점입니다.
string a = "'abc'".Replace('\'', default(char)).Trim();
Console.WriteLine("a: {0} (Length: {1})", a, a.Length);
string b = "'abc'".Replace('\'', Char.MinValue).Trim();
Console.WriteLine("b: {0} (Length: {1})", b, b.Length);
string c = "'abc'".Replace('\'', (char)0).Trim();
Console.WriteLine("c: {0} (Length: {1})", c, c.Length);
string d = "'abc'".Replace('\'', '\0').Trim();
Console.WriteLine("d: {0} (Length: {1})", d, d.Length);


 

앞/뒤로 붙은 null character를 제거하려면 null character를 명시하는 작업이 필요합니다. 그리고 이것은 Replace 메서드에 대해서도 동일하게 적용됩니다.
</pre>
<pre>string a = "'abc'".Replace('\'', default(char)).Trim('\0');
Console.WriteLine("a: {0} (Length: {1})", a, a.Length);
string b = "'abc'".Replace('\'', Char.MinValue).Trim('\0');
Console.WriteLine("b: {0} (Length: {1})", b, b.Length);
string c = "'abc'".Replace('\'', (char)0).Trim('\0');
Console.WriteLine("c: {0} (Length: {1})", c, c.Length);
string d = "'abc'".Replace('\'', '\0').Trim('\0');
Console.WriteLine("d: {0} (Length: {1})", d, d.Length);


이런 맥락에서 보았을 때, 외부로부터 들어오는 입력 문자열에 대해 엄격하게 이야기하자면, null character에 대한 것을 String.Empty로 치환하는 작업도 필요할 수 있다고 볼 수 있겠습니다.

 

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2013. 10. 25. 23:00

NUnit의 GUI Runner는 여러 개의 테스트 유닛 프로젝트를 로드하여 동시에 테스트 결과를 시각적으로 확인할 수 있는 매우 유용한 유틸리티입니다. 그러나 한 가지 아쉬운 점이 있다면, Visual Studio와 완벽하게 통합되어있지는 않아서 단위 테스트 도중 변수의 상태를 확인하거나 디버깅을 하기에는 불편한 구조로 제작되어있다는 점입니다. 그래서 개인적으로 자주 애용하는 대안으로 Reflection을 사용하여 Test Fixture와 Test Case를 검색하여 자동으로 호출하는 유틸리티 클래스의 소스 코드를 https://github.com/rkttu/nunit-self-runner 에 게시하였습니다.

이 프로그램 코드는 NUnit Framework 어셈블리 외에 특별한 종속성이 없고 어떤 코드에서든 쉽게 붙여넣어 시작할 수 있습니다. 그러나 기능 상의 제약이 있는데 다음과 같은 유형의 Test Fixture나 Test Case에서는 작동하지 않습니다.

  • Test Fixture 생성 시 별도의 생성자 매개 변수가 필요한 경우
  • Test Method 실행 시 별도의 호출 매개 변수가 필요한 경우
  • private이나 protected, internal 멤버

이 소스 코드를 NUnit 클래스 라이브러리 프로젝트에 추가하고, 해당 NUnit 클래스 라이브러리를 컴파일하여 실행하면 다음과 같은 형태로 단위 테스트가 전개될 것입니다.

테스트에 실패하는 케이스, 즉 Exception이 발생하면 위와 같이 적색의 Test case failed 라는 문구가 나타나고 자세한 Stack Trace 결과가 노란색의 텍스트로 표시되어 시각적으로 구분을 쉽게 해줍니다. 그리고 실패했다는 사실을 알리기 위하여 테스트가 일시 중단되고, Enter 키를 누르면 계속 실행됩니다. 이 메시지를 확인하고 적절한 위치에 중단점을 설정하면 디버거가 해당 위치에서 중지되므로 좀 더 쉽게 문제를 진단할 수 있습니다.

반면 예외 없이 정상적으로 실행되는 테스트 케이스는 초록색의 Test case succeed 메시지를 표시하고 중단없이 계속 다음 테스트를 진행합니다. 그리고 한 Test Fixture의 실행이 완료되면 다시 사용자의 입력을 대기하는 상태로 들어가며, Enter 키를 누르면 다음 Test Fixture로 진행할 수 있으므로 인터랙티브하게 단위 테스트 결과를 확인할 수 있습니다. 

모든 테스트 Fixture의 실행이 끝난 이후에도 한 번 더 사용자의 입력을 기다립니다. 콘솔에 표시된 전체 내용을 리뷰하고 마지막으로 Enter 키를 누르면 프로그램이 완료됩니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

IaaS2013. 10. 20. 22:30

Windows Azure의 Virtual Machine 서비스는 Windows와 Linux를 Guest OS로 지원하는 전형적인 IaaS 플랫폼입니다. 그리고 Linux는 다양한 오픈 소스 소프트웨어와 결합할 수 있는 매우 이상적인 소프트웨어 개발 환경이기도 합니다.

Linux에서 사용할 수 있는 매력적인 소프트웨어들 중 최근 큰 주목을 받고 있는 프로젝트로 docker 프로젝트가 있는데, 이 프로젝트는 기본적으로 Hypervisor 없이 Linux 실행 환경을 가상화하고 서로 격리된 상태로 실행할 수 있도록 도와주는 Linux Container (LXC)를 조금 더 실용적이고 사용하기 편리하게 만들어주는 컴패니언 소프트웨어로, 이미지를 공유하거나, 이미지로부터 생성하는 컨테이너를 만들기 위해 필요한 명령을 자동으로 등록하거나, 컨테이너를 이미지로 변환하는 등의 작업을 단순화합니다.

docker 프로젝트를 설치하고 사용하는 방법에 대한 가이드는 인터넷 상에 이미 다양한 자료로 게시된 적이 있고, 최근에 열린 NAVER 개발자 행사인 DeVIEW 2013에서도 다루어진 적이 있습니다. (http://www.slideshare.net/modestjude/docker-in-deview-2013)

오늘 살펴보려는 내용은 docker 프로젝트를 Windows Azure Virtual Machine 상에서 설치하고 이용하는 방법과 함께, docker Index에 게시되어있는 최신 버전의 Mono 이미지를 다운로드하고 활용하는 방법을 간단히 살펴보려고 합니다. 지금 소개하는 방법을 통해서 쉽고 빠르게 리눅스 기반의 다중 개발 환경을 손쉽고 빠르게 프로토타이핑할 수 있습니다.

시작하기 전에 - Hypervisor 안에서 또다른 가상 환경을 만드는 것은 불가능하지 않습니까?

docker를 일반적인 PC나 서버 환경이 아닌 곳에서 사용할 때 가장 먼저 드는 의문점이 바로 이것입니다. 기본적으로 Hypervisor 위에서 실행하는 OS는 또 다시 가상 환경을 만들어낼 능력이나 여건이 되지 못합니다. 가능하도록 설정했다고 해도 결국 물리적인 한계에 부딪힐 가능성이 커집니다.

사실, docker는 Hypervisor가 아니기 때문에 Hypervisor 고유의 CPU 기능을 활용하는 일은 거의 없고, 호스트가 되는 리눅스의 커널의 재량에 따라 그 안에서 실행되는 독립적인 프로세스일 뿐입니다. 그러나, 제아무리 docker가 유용하다고 해도, 시스템이나 VM에 할당된 자원의 밀도나 품질을 생각해보았을 때 docker가 실제 처리할 수 있는 작업의 양이 항상 효율적이라고는 할 수 없습니다. 따라서, docker를 사용한 시스템 구축은 전적으로 충분한 시나리오 테스트와 QA를 거쳐야만 함을 염두에 두어야 할 것입니다.

docker로 할 수 있는 일

docker는 단순히 프로세스만을 격리하는 것이 아니라 일정 수준의 가상 환경을 다룹니다. 즉, 자체적으로 이용할 수 있는 파일 시스템, 네트워크 어댑터, 가용 메모리 크기 등이 있고, 상황에 따라 이들 자원의 크기가 동적으로 변화하게 됩니다. 그러나 우리가 일반적으로 사용하는 완전한 Hypervisor와는 다르게 자원을 명시적으로 제한할 수 있는 방법이 2013년 10월 현재 기준으로 특별히 없습니다. 그리고 네트워크는 사설 IP로만 할당되기 때문에, docker가 자체적으로 구성하는 NAT를 이용하여 외부로부터 들어오는 네트워크 요청을 특정 컨테이너 앞으로 도착하도록 연결해주는 것이 꼭 필요합니다.

그럼에도 불구하고, docker는 리눅스 기반의 환경에서 항상 있을 수 있는 파일 시스템, 커널, 잘못된 라이브러리나 패키지 설치로 인한 시스템의 중단으로부터 안전하게 지켜줄 수 있고, 신뢰할 수 있을만한 수준을 제공하면서도, 가볍게 다룰 수 있는 가상 환경을 제공한다는 점에서 큰 주목을 받고 있으며, 심지어 Hypervisor 기반의 실행 환경 위에서 전혀 다른 Linux Guest를 추가 실행할 수 있을만큼 유연합니다.

docker Index (https://index.docker.io/)에 게시된 이미지들을 살펴보면 알겠지만 호스트의 Linux OS와 아무 관련이 없는 busybox 같은 응급 이미지도 존재하고, Ubuntu가 호스트인 시스템에서 CentOS를 컨테이너 OS로도 택하는 것이 가능합니다. 즉, docker 환경에 맞추어 개발된 OS이기만하면 docker와의 상호작용을 전제로 호스트 OS와 완전히 분리된 환경에서 실행이 가능하므로 독립적인 환경 구성이 가능함을 뜻합니다.

docker를 Azure Linux VM 위에 설치하기

docker는 LXC 프로젝트를 기반으로 하기 때문에, 커널 버전에 대한 의존성이 크고, 사용할 수 있는 Host OS의 종류에도 제한이 있습니다. 현 시점에서는 Ubuntu Linux 13.04에서의 실행이 가장 안정적이기 때문에, Windows Azure Virtual Machine 갤러리에서 다음 그림과 같이 Ubuntu Linux 13.04 기반의 VM을 하나 추가해서 시작하셔야 합니다. 만약 Ubuntu Linux 12.04나 12.10 버전을 실행 중인 경우 Secure Shell 터미널 환경을 통하여 원격으로 13.04로 업그레이드하는 명령을 실행할 수도 있지만, libcurse 기반의 UI 실행이 일부 필요하기 때문에 putty 등에서는 정상적으로 보이지 않을 수 있고, 또한 잘못 선택할 경우 VM에 원격 접속이 불가능한 상황이 올 수 있으므로 추천하지 않습니다.

http://manage.windowsazure.com/ 으로 접속하여 새 VM을 갤러리로부터 생성하도록 시작합니다. 아래와 같은 대화 상자가 나타나는지 확인한 후 Ubuntu Linux 13.04를 선택합니다.

 

다음 버튼을 클릭한 다음 기본 VM 설정을 입력합니다.

 

PuttyGen을 이용하여 키 체인을 만들어 업로드하거나, 사용자 암호를 지정하고 다음 버튼을 클릭합니다.

 

클라우드 서비스는 네트워크 연결 및 중재를 위한 기본 단위이자 실행 환경을 정의하는 단위 환경입니다. docker 환경과 연결하려는 클라우드 서비스나 다른 VM이 있을 경우 같이 소속되도록 설정해주시고, 가용성 설정 등을 확인한 다음 다음 버튼을 클릭합니다.

 

기본적으로 SSH 포트가 열려있습니다. 그러나 docker container와의 연결을 허용하고 외부에서 접속을 받아들이려면 Windows Azure의 방화벽 설정도 수정해야 합니다. 외부에서 docker container 서비스로의 접속이 안된다면 이쪽의 방화벽 설정을 꼭 확인하셔야 합니다. 마침 버튼을 클릭하여 VM 생성을 시작합니다.

 

VM의 외부 DNS 주소를 확인하고, putty로 접속을 시작합니다.

 

접속이 완료되었다면 이제부터 명령어 입력을 진행합니다. 설치 가이드의 내용은 http://docs.docker.io/en/latest/installation/ubuntulinux/#ubuntu-raring-13-04-64-bit 에서 발췌하였습니다.

우선 최신 패키지 목록을 가져오기 위하여 다음 명령을 수행합니다. 최신 릴리즈를 사용하여 VM을 만들었다면 별 다른 업데이트는 발생하지 않을 것입니다.

sudo apt-get update

그리고 Ubuntu 13.04 시스템들 중 일부 릴리즈에서 누락되어있을 수 있는 AUFS 파일 시스템에 대한 지원 (LXC 실행을 위해 꼭 필요합니다.)을 추가하기 위하여 아래 명령어를 수행합니다. 참고로 Azure Virtual Machine을 통하여 최신 릴리즈를 사용하도록 VM을 생성했다면 역시 AUFS에 대한 지원이 이미 포함되어있어서 아래 명령어로 시스템에 변화가 발생하지는 않을 것입니다.

sudo apt-get install linux-image-extra-`uname -r`

이제 docker 리포지터리에 접근하여 패키지를 설치할 차례입니다. 우선 키 체인을 다운로드하여 시스템에 등록하여 docker 패키지를 인터넷으로부터 다운로드할 수 있도록 허가합니다.

sudo sh -c "wget -qO- https://get.docker.io/gpg | apt-key add -"

OK라는 메시지를 확인하였으면 이어서 리포지터리 목록에 docker 리포지터리를 추가하기 위하여 다음 명령어를 실행합니다.

sudo sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"

이제 패키지 업데이트를 다시 수행하여 사용 가능한 패키지 목록을 갱신합니다.

sudo apt-get update

출력 중에서 다음과 비슷한 메시지가 들어있는지 확인합니다.

Get:3 http://get.docker.io docker/main amd64 Packages [1,395 B]

이제 패키지 목록을 업데이트하였으므로 lxc-docker 패키지가 사용 가능한 상태가 되었을 것입니다. lxc-docker 패키지를 아래 명령으로 설치합니다.

sudo apt-get install lxc-docker

종속 패키지들을 다수 설치해야 함을 알리는 메시지가 나타나면 y 키를 눌러 진행합니다.

설치가 잘 되었는지 확인해보기 위하여 docker Index 사이트로부터 ubuntu 게스트 OS 이미지를 다운로드해보겠습니다. 아래 명령어를 실행합니다.

sudo docker run -i -t ubuntu /bin/bash

아래와 같이 다운로드 메시지가 나타나고 콘솔이 바뀌는 것을 확인하기 바랍니다.

rkttu@dockertest:~$ sudo docker run -i -t ubuntu /bin/bash
Unable to find image 'ubuntu' (tag: latest) locally
Pulling repository ubuntu
8dbd9e392a96: Download complete
b750fe79269d: Download complete
27cf78414709: Download complete
root@f45ee37cf476:/#

호스트 이름이 Azure VM의 dockertest가 아니라 임의로 작명한 f45ee37cf476이라는 이름으로 바뀐 것을 볼 수 있습니다. 그리고 IP 주소 대역도 다르다는 것을 쉽게 파악할 수 있는데, ifconfig을 비롯한 네트워킹 도구가 이 버전의 이미지에는 들어있지 않기 때문에 다음 명령어를 실행하여 net-tools 패키지를 설치합니다.

apt-get install net-tools

격리 환경 상에서 자동으로 root 권한을 얻었으므로 sudo를 덧붙일 필요가 없습니다. 설치가 끝난 다음, ifconfig eth0 명령을 실행하면 다음과 같이 나타납니다.

eth0      Link encap:Ethernet  HWaddr fa:b2:4f:b9:15:84
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          inet6 addr: fe80::f8b2:4fff:feb9:1584/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:192 errors:0 dropped:0 overruns:0 frame:0
          TX packets:81 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:267507 (267.5 KB)  TX bytes:5591 (5.5 KB)

굵게 강조 표시한대로 사설 IPv4 주소가 할당되어있습니다. 그리고 패키지 업데이트와 업그레이드를 진행하여 인터넷 연결 상태를 다시 한 번 확인해봅니다.

apt-get update
apt-get upgrade

가상 환경에서 나가기 위하여 exit 명령을 입력하면 다음과 같이 원래의 Host OS로 프롬프트가 바뀌는 것을 볼 수 있습니다.

root@f45ee37cf476:/# exit
exit
rkttu@dockertest:~$

이제 방화벽 설정을 확인합니다. 기본적으로 Ubuntu는 ufw라는 방화벽 프로그램을 이용합니다. 그리고 Windows Azure 기본 구성 이미지에서는 ufw가 비활성화되어있고, Windows Azure의 방화벽이 외부로부터의 연결을 차단하며, Windows Azure 간 네트워크에는 제한이 없습니다. 아래 명령어를 입력하여 방화벽 상태를 확인합니다.

rkttu@dockertest:~$ sudo ufw status
Status: inactive
rkttu@dockertest:~$

그리고 방금 전 테스트를 위하여 받은 이미지와 그 이미지를 기반으로 실행한 컨테이너가 잘 등록되었는지 확인하여 설치 프로세스를 마무리합니다.

rkttu@dockertest:~$ sudo docker images -a
REPOSITORY          TAG                 ID                  CREATED             SIZE
ubuntu              12.04               8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu              latest              8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu              precise             8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu              12.10               b750fe79269d        7 months ago        24.65 kB (virtual 180.1 MB)
ubuntu              quantal             b750fe79269d        7 months ago        24.65 kB (virtual 180.1 MB)
<none>              <none>              27cf78414709        7 months ago        180.1 MB (virtual 180.1 MB)

rkttu@dockertest:~$ sudo docker ps -a
ID                  IMAGE               COMMAND             CREATED             STATUS              PORTS
f45ee37cf476        ubuntu:12.04        /bin/bash           8 minutes ago       Exit 0

예상한 대로 이미지가 다운로드되어있고, 해당 이미지를 기반으로 /bin/bash 앱에 대한 컨테이너가 생성 후 실행되었으며 종료 코드 0으로 종료되었다는 결과 표가 보입니다.

mono 개발 환경 빠르게 구축하기

mono 개발 환경을 입맛에 맞게 구축하는 방법은 여러가지가 있습니다. 방금 전처럼 base image를 받아서 수작업으로 설치하거나, 그 과정을 서술하는 Dockerfile을 만들어 한 번에 일괄 실행하여 시스템의 설치를 전개하는 방식도 있을 수 있습니다. 그렇지만 docker를 개발 환경으로 이용하기 위해서 취할 수 있는 가장 좋은 방법은 docker Index 사이트에 게시된 최신 이미지를 확인하여 해당 이미지를 직접 로컬 시스템으로 Pull 하는 것입니다.

편의를 위하여 잠시 리눅스 콘솔에서 윈도 화면으로 되돌아온 다음 https://index.docker.io/ 로 접속하여 키워드로 mono를 지정하고 검색합니다.

 

 

Ubuntu 이미지를 이용하여 Mono 3.2.3을 설치하여 배포하는 이미지가 Docker Index에 올라와있습니다. 그 외에도, 닷넷 기반의 SOA 실행 및 개발 환경 구축을 편리하게 할 수 있도록 Service Stack과 연계한 리눅스 이미지도 보입니다. 우리가 사용하려는 것은 rwentzel/ubuntu-mono 이미지이므로 이 이미지의 이름을 기록합니다.

이제 다시 리눅스 콘솔로 되돌아가서 해당 이미지를 로컬 리포지터리로 다운로드하겠습니다. 다음 명령어를 실행하여 동기화를 시작합니다. 해당 이미지는 여러 차례 수정을 거쳐 만들어진 것이기 때문에 다운로드에 다소 시간이 걸리니 조금 오래 기다리셔야 합니다.

sudo docker pull rwentzel/ubuntu-mono

이미지 다운로드가 완료되었다면, 이제 이 이미지를 이용하여 컨테이너를 만들고 정말 안에 mono 개발 환경이 들어있는지 확인해볼 차례입니다. 아래 명령어로 이미지를 우선 확인합니다.

sudo docker images -a

설치한 이미지의 갯수가 매우 많아졌습니다. 그런데 주의할 것이 하나 있습니다. docker rmi 명령으로 이미지를 제거하는 것이 가능하지만, 꼭 필요한 경우가 아니라면 가급적 리포지터리나 TAG가 none으로 설정된 이미지를 임의로 삭제하는 일은 피해야 합니다. 콘솔에서는 잘 드러나지 않지만 이미지는 차이점 보관 방식으로 생성되어있고 일종의 트리 계층을 형성하기 때문입니다. 그래서 docker로 이미지를 만들 때 정말 중요하게 관리되어야 하는 이미지는 REPOSITORY나 TAG에 정확한 속성을 지정하여 쉽게 찾을 수 있도록 해주는 것이 중요합니다.

REPOSITORY             TAG                 ID                  CREATED             SIZE
rwentzel/ubuntu-mono   latest              2e8ec476cfd1        3 weeks ago         12.29 kB (virtual 2.627 GB)
<none>                 <none>              866ee2ba174c        3 weeks ago         12.29 kB (virtual 2.627 GB)
<none>                 <none>              9d58fdd1f145        3 weeks ago         28.67 kB (virtual 2.627 GB)
<none>                 <none>              48d313d93277        3 weeks ago         194.1 kB (virtual 2.627 GB)
<none>                 <none>              a6f3f7d033e8        3 weeks ago         1.151 GB (virtual 2.627 GB)
<none>                 <none>              0063533722a2        3 weeks ago         486.2 MB (virtual 1.476 GB)
<none>                 <none>              563cc9ce1df7        3 weeks ago         43.2 MB (virtual 989.9 MB)
<none>                 <none>              d963202bdca8        3 weeks ago         62.24 MB (virtual 946.7 MB)
<none>                 <none>              fa1d9d247e8a        3 weeks ago         27.46 MB (virtual 884.5 MB)
<none>                 <none>              e01eae29dae1        3 weeks ago         32.86 kB (virtual 857 MB)
<none>                 <none>              eb5606044c61        3 weeks ago         70.23 MB (virtual 857 MB)
<none>                 <none>              519b96c9a701        3 weeks ago         29.08 MB (virtual 786.8 MB)
<none>                 <none>              552c68e56d9a        3 weeks ago         46.38 MB (virtual 757.7 MB)
<none>                 <none>              17f3c8064eb6        3 weeks ago         25.59 MB (virtual 711.3 MB)
<none>                 <none>              0cb9cc3fc7b8        3 weeks ago         144.5 MB (virtual 685.7 MB)
<none>                 <none>              898780b65670        3 weeks ago         12.29 kB (virtual 541.2 MB)
<none>                 <none>              de6790a79ec8        3 weeks ago         158.2 MB (virtual 541.2 MB)
<none>                 <none>              29002fa46318        3 weeks ago         24.58 MB (virtual 383 MB)
<none>                 <none>              270acf4d2474        3 weeks ago         96.52 MB (virtual 358.5 MB)
<none>                 <none>              1d4aaea09576        3 weeks ago         81.83 MB (virtual 261.9 MB)
ubuntu                 12.04               8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu                 latest              8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu                 precise             8dbd9e392a96        6 months ago        131.5 MB (virtual 131.5 MB)
ubuntu                 12.10               b750fe79269d        7 months ago        24.65 kB (virtual 180.1 MB)
ubuntu                 quantal             b750fe79269d        7 months ago        24.65 kB (virtual 180.1 MB)
<none>                 <none>              27cf78414709        7 months ago        180.1 MB (virtual 180.1 MB)

위의 rwentzel/ubuntu-mono 이미지를 사용하여 내부에 들어있는 /bin/bash를 컨테이너로 실행하기 위하여 아래 명령을 실행합니다.

sudo docker run -i -t rwentzel/ubuntu-mono /bin/bash

그러면 다음과 같이 프롬프트가 변경되는 것을 볼 수 있습니다.

rkttu@dockertest:~$ sudo docker run -i -t rwentzel/ubuntu-mono /bin/bash
root@f739c613d0ae:/#

이제 간단한 C# 소스 코드를 작성하여 프로그램으로 컴파일하고 잘 작동하는지 확인해보겠습니다. vi를 사용해도 좋고, vi 사용에 익숙하지 않은 경우 아래와 같이 명령을 실행하여 pico/nano 에디터를 추가 설치할 수 도 있습니다.

apt-get install nano

Hello.cs 라는 소스 코드를 원하는 에디터로 아래와 같이 작성합니다.

using System;
using System.Linq;
using System.Collections.Generic;

public static class Program {
        [STAThread]
        public static void Main(string[] args) {
                var count = args.Count();
                List<string> options = args.Where(x => x.StartsWith("-")).ToList();
                Console.Out.WriteLine("Hello, World!");
                Console.Out.WriteLine("Total Args: {0}, Option Args: {1}", count, options.Count);
        }
}

Mono 3.2.3은 LINQ와 제네릭을 모두 잘 지원하므로 위의 코드를 아래와 같이 컴파일하였을 때 문제없이 컴파일이 완료될 것입니다.

mcs Hello.cs

그리고 JVM과 마찬가지로 Mono VM을 실행하여 컴파일한 어셈블리 파일을 실행해봅니다.

root@f739c613d0ae:/# mono Hello.exe
Hello, World!
Total Args: 0, Option Args: 0
root@f739c613d0ae:/# mono Hello.exe a b c
Hello, World!
Total Args: 3, Option Args: 0
root@f739c613d0ae:/# mono Hello.exe a b -c
Hello, World!
Total Args: 3, Option Args: 1

의도한 대로 LINQ와 제네릭을 잘 받아서 처리하고 있습니다.

mono 실행 속도 개선하기

최신 버전의 mono는 실행 속도를 개선하기 위하여 가비지 컬렉터를 새롭게 디자인하였고, 전처리 컴파일을 미리 수행하는 방법을 제공합니다. 특히, Microsoft .NET Framework와 마찬가지로 GAC에 대해 ngen을 수행하는 것과 비슷하게 AOT 컴파일을 미리 수행하도록 명령어를 한 번 실행해주면 실행 속도 개선에 큰 도움이 됩니다. 아래 명령어를 실행하여 GAC 내부의 모든 어셈블리에 대해 AOT 컴파일을 실행합니다.

for i in /usr/local/lib/mono/*/mscorlib.dll; do mono --aot $i; done
for i in /usr/local/lib/mono/gac/*/*/*.dll; do mono --aot $i; done

위의 이미지 환경 내에서의 mono 설치 경로는 /usr/local에 있으므로 경로는 mono 실행 파일의 위치를 which 명령으로 확인하여 적절하게 변경해야 합니다. 참고로 GAC에 대한 AOT 컴파일은 시간이 오래 걸릴 수 있으며, 이 버전의 가상 환경에서는 .NET Framework 1.0이나 1.1 기준으로는 개발이 불가능하므로 버전을 업그레이드 하거나 base image로부터 구 버전의 mono를 설치하도록 수동 구성해야 합니다.

그리고 개별 어셈블리에 대한 AOT 컴파일은 다음과 같이 실행할 수 있으며, 실행 결과로 .so 파일이 생성되므로 AOT 컴파일의 효과를 위하여 항상 같은 위치에 배포될 수 있도록 배포합니다.

mono --aot Hello.exe
mono Hello.exe

마무리

지금까지 Windows Azure Linux VM에서 docker를 이용한 mono 개발 환경의 구축 방법을 살펴보았습니다. 언제든 원하는 때에 즉시 Linux VM을 만들 수 있다는 것 말고도, 한 번 만든 VM을 손상시키지 않으면서 환경을 독립적으로 구성할 수 있도록 하는 환경 상의 완결성을 제공하는 docker를 이용함으로서 최상의 리눅스 개발 환경을 체험할 수 있게 된 것은 참 좋은 일입니다.

그리고 한 가지 더 덧붙이면, docker를 이용하여 컨테이너를 만들 때 -v 스위치를 사용하여 호스트 파일 시스템과 링크를 연결할 수 있으므로, 컨테이너 셸 상에서 만든 파일을 쉽게 호스트로 반출하거나 반입할 수 있습니다. -p 스위치는 가상 NAT를 통하여 포트 리디렉션을 할 수 있는 방법을 제공하며, 양쪽 스위치의 자세한 사용법은 http://blog.docker.io/2013/07/docker-0-5-0-external-volumes-advanced-networking-self-hosted-registry/ 의 내용을 확인하기 바랍니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2013. 10. 18. 22:00

C#에서 프로그램 코드를 전개하는 방법은 상대적으로 다른 언어에 비해 자유도가 높은 편입니다. 그렇지만 이런 기능들을 잘 모를 경우 코드 품질이 낮아질 수도 있고, 이해하기 어려운 코드가 되기 쉽습니다. 이러한 문제점을 극복할 수 있는 실용적 코드 작성 팁 몇 가지를 공유해보도록 하겠습니다.

양보하기 어려운 변수 작명을 만났다면?

코딩을 하다보면 그런 경우가 있습니다. 밖으로 드러내는 것이든, 안에서 사용하는 것이든 코드의 의도를 정확히 설명하기 위해서 양보하기 어려운 변수 작명을 고수해야 할 때가 있습니다. 이럴 때에는 고민하지 말고, 변수명 앞에 @ 기호를 지정해주기만 하면 됩니다. C#의 주요 키워드들 (상황에 따라 예약되는 키워드는 이 문제를 만날 가능성이 적습니다.) 상당수를 이 방법을 사용하여 약간 바꾸어 변수 작명으로 채용하는 것이 얼마든지 가능합니다.

string
    @abstract = string.Empty,    @as = string.Empty,    @base = string.Empty,    @bool = string.Empty,
    @break = string.Empty,    @byte = string.Empty,    @case = string.Empty,    @catch = string.Empty,
    @char = string.Empty,    @checked = string.Empty,    @class = string.Empty,    @const = string.Empty,
    @continue = string.Empty,    @decimal = string.Empty,    @default = string.Empty,    @delegate = string.Empty,
    @do = string.Empty,    @double = string.Empty,    @else = string.Empty,    @enum = string.Empty,
    @event = string.Empty,    @explicit = string.Empty,    @extern = string.Empty,    @false = string.Empty,
    @finally = string.Empty,    @fixed = string.Empty,    @float = string.Empty,    @for = string.Empty,
    @foreach = string.Empty,    @goto = string.Empty,    @if = string.Empty,    @implicit = string.Empty,
    @in = string.Empty,    @int = string.Empty,    @interface = string.Empty,    @internal = string.Empty,
    @is = string.Empty,    @lock = string.Empty,    @long = string.Empty,    @namespace = string.Empty,
    @new = string.Empty,    @null = string.Empty,    @object = string.Empty,    @operator = string.Empty,
    @out = string.Empty,    @override = string.Empty,    @params = string.Empty,    @private = string.Empty,
    @protected = string.Empty,    @public = string.Empty,    @readonly = string.Empty,    @ref = string.Empty,
    @return = string.Empty,    @sbyte = string.Empty,    @sealed = string.Empty,    @short = string.Empty,
    @sizeof = string.Empty,    @stackalloc = string.Empty,    @static = string.Empty,    @string = string.Empty,
    @struct = string.Empty,    @switch = string.Empty,    @this = string.Empty,    @throw = string.Empty,
    @true = string.Empty,    @try = string.Empty,    @typeof = string.Empty,    @uint = string.Empty,
    @ulong = string.Empty,    @unchecked = string.Empty,    @unsafe = string.Empty,    @ushort = string.Empty,
    @using = string.Empty,    @virtual = string.Empty,    @void = string.Empty,    @volatile = string.Empty,
    @while = string.Empty,    @__arglist = string.Empty,    @__refvalue = string.Empty,    @__makeref = string.Empty,
    @__reftype = string.Empty;

위의 코드를 컴파일하였을 때 사용하지 않는 변수라는 경고를 제외하고 컴파일에는 이상이 없음을 확인할 수 있습니다.

String.Join 메서드와 같이 시작과 끝에 구분 기호 (Delimiter)가 붙지 않는 문자열 더하기를 수행하는 방법

간혹 그런 경우가 있습니다. 기존 컬렉션으로부터 새로운 컬렉션을 만들면서 시작이나 끝에는 구분자 기호나 원소를 붙이지 않고 중간에만 원하는 내용을 삽입하고 싶을 때가 있는데, 이런 경우 인덱스를 사용하려고 하거나 굳이 배열로 변환하려는 노력을 하게 될 수 있는데, 이는 별로 바람직하지 않습니다. 대신, IEnumerator 인터페이스와 if 문 한번, while 문 한 번으로 나누어 반복문을 써주기만 하면 쉽게 문제가 해결됩니다. 참고로, C#의 foreach 문은 IEnumerator 인터페이스에 대한 포장입니다.

String.Join 메서드와 같은 기능을 하는 메서드를 만들기 위하여, 아래와 같이 코드를 작성할 수 있을 것입니다.

static string Join<T>(string delim, IEnumerable<T> cols)
{
    StringBuilder buffer = new StringBuilder();
    IEnumerator<T> @enum = cols.GetEnumerator();

    if (@enum.MoveNext())
        buffer.Append(@enum.Current);

    while (@enum.MoveNext())
    {
        buffer.Append(delim);
        buffer.Append(@enum.Current);
    }

    return buffer.ToString();
}

위의 메서드를 이용하여 문자열의 각 문자들 사이에 쉼표를 붙이는 것을 쉽게 처리할 수 있습니다.

string modified = Join<char>(", ", "Hello guys!");
Console.WriteLine(modified);

H, e, l, l, o,  , g, u, y, s, !

현재 컴퓨터를 기준으로 언제나 유일한 값을 빠르게 만들어내는 방법

완벽한 의미에서의 유일성은 상당히 많은 Factor를 반영해야만 그 성격을 보장할 수 있습니다. 그러나, 대개의 경우 지구상에서 유일한 값을 만들어내는것 보다는, 현재 실행 중인 컴퓨터나 데이터베이스를 기준으로 유일한 값을 만들어내는 것 정도만으로도 충분히 목표를 달성할 수 있습니다. 이럴 경우에도 매번 GUID를 생성하거나, 데이터베이스의 Identity Seed를 사용하는 것은 비용이 많이 들고, 특히 데이터베이스의 Identity Seed는 데이터베이스마다 커스터마이징 정도의 차이가 있지만 대개는 생성된 값을 클라이언트 측에서 확인하기 어렵기 때문에 Round Trip을 유발합니다.

지금 소개하는 방법은 이러한 문제점을 극복하면서도 매우 빠른 실행 속도를 보장하는 유일 값 생성 방법입니다. 바로, 현재 시스템의 Tick Count를 그대로 이용하는 방법입니다. Tick Count는 100 나노초 단위이므로 일정한 수준에서의 유일성을 보장하기에는 충분한 밀도가 됩니다. 그리고 생성하는 값의 데이터 형식이 64비트 정수이므로 범위 또한 충분히 넓습니다.

long uniqueVal = DateTime.UtcNow.Ticks;

위와 같이 값을 얻어올 수 있고, 위의 값을 데이터베이스에 레코드를 추가할 때 힌트용으로 사용하는 열에 지정하면 삽입 즉시 조회할 수 있는 고유한 값이 되므로 프로그램 로직 개선에 많은 도움이 됩니다.

조건문의 분기를 임의로 결정하도록 만드는 방법

Modular Operator (%)의 기능과 특징을 아신다면 당연하게 받아들일 수 있는 내용이지만, 이런 특이한 상황에 대해서 유용하게 쓰일 수 있습니다. switch나 if/else 등의 조건문의 분기 자체를 임의 결정할 수 있도록 시뮬레이션해야 하는 상황에서 난수 값이 구체적으로 어떤지를 검색하거나 값을 한정하기 위해서 제약하는 것보다 더 손쉽고 이해하기 편한 시뮬레이션 방식을 % 연산자를 이용하여 쉽게 구현할 수 있습니다.

string modified = Join<char>(", ", "Hello guys!");
Random random = new Random();
char x = '\0';

for (int i = 0; i < 100; i++)
{
    switch (Char.ToUpperInvariant(modified[random.Next() % modified.Length]))
    {
        case 'H': x = 'i'; break;
        case 'E': x = 'f'; break;
        case 'L': x = 'm'; break;
        case 'O': x = 'p'; break;
        case ' ': x = '?'; break;
        case 'G': x = 'h'; break;
        case 'U': x = 'v'; break;
        case 'Y': x = 'z'; break;
        case 'S': x = 't'; break;
        case '!': x = '@'; break;
        case ',': x = '.'; break;
        default: x = ' '; break;
    }
    Console.Write(x);
}
Console.WriteLine();

위와 같이 % 기호 다음에 오는 operand로 컬렉션의 길이나 배열의 길이를 지정해주면, 배열의 요소를 임의로 고를 수 있어서 활용폭이 더 넓어집니다.

소스 코드에 특수문자나 CJK 문자를 안전하게 기록하고 다른 사람과 공유하는 방법

드문 경우이지만, 주석 이외에 프로그램의 실행에 실제로 영향을 줄 가능성이 있는 문자열이 영어나 숫자, 혹은 ASCII 범위의 문자가 아닐 경우 다른 환경이나 언어 구성에서 소스 코드 파일을 편집한 후 되돌려받았을 때 문자열이 깨지는 일이 자주 있습니다. 지금 이야기하는 방법은 사실 실용적이지는 않지만, 정말 중요하게 지켜야 할 리소스라면 지금 소개하는 방법을 이용하여 번거롭지만 확실하게 문자열 데이터를 지키는 것도 가능하니 한 번 고려해보시는 것도 좋을 것 같습니다.

예를 들어, 중국어 문자열 "我国屈指可数的财阀。" (우리나라 굴지의 재벌)이 소스 코드에 문자열로 저장되어있고 이 문자열을 인코딩 문제로부터 보호하기 위해서, 위의 문자열을 복사하여 LINQPAD에 아래의 인라인 식에 치환하여 넣습니다. (LINQPAD는 http://www.linqpad.net 에서 다운로드합니다.)

String.Join(", ", "paste here".Select(x => "0x" + ((int)x).ToString("X4")))

그러면 다음과 같은 결과가 나타납니다.

0x6211, 0x56FD, 0x5C48, 0x6307, 0x53EF, 0x6570, 0x7684, 0x8D22, 0x9600, 0x3002

이제 위의 내용을 new String(new char[] { 0x6211, 0x56FD, 0x5C48, 0x6307, 0x53EF, 0x6570, 0x7684, 0x8D22, 0x9600, 0x3002
 }); 와 같이 바꾸어서 소스 코드에 저장하면 실행 시 원래 문자열로 복원되면서도, 소스 코드 상의 문자열이 훼손될 걱정을 하지 않아도 됩니다. 단, 이 경우 소스 코드의 내용만으로는 실제로 어떤 문자열인지 파악하기 어려워진다는 장점이자 단점이 동시에 발생합니다. 장점으로는, 일종의 난독처리가 이루어진 셈이며, 단점으로는, 관리가 어려워진 셈이기 때문입니다.

조건문을 어떻게 관리하십니까?

조건문을 어떻게 작성하고 관리하는가에 대한 문제는 개인의 취향과 논리에 따라 매우 다양한 패턴이 존재합니다. 그러나 경험 상, 코드가 간결할 수록 유리하다는 것은 보편적으로 통하는 진리입니다. 개인적인 경험으로 유추해볼 때, 코드의 간결함은, 조건문이나 분기가 얼마나 단일 메서드 내에서 잘 관리되고 있는가에 대한 이야기로 바꾸어 말할 수도 있을 것 같습니다.

이런 방침에 따라, C나 C++ 스타일의 언어들은 중첩해서 사용하는 중괄호의 여닫음 횟수가 늘어날수록 복잡도가 크게 증가합니다. C#도 예외는 아닌데, 이런 이유때문에 저는 스스로 조건문이나 코딩 스타일을 나름의 원칙을 정하여 사용하고 있습니다.

우선, 단위 메서드를 작성하기에 앞서서 조건 검사를 할 때에는 부정적인 시나리오부터 먼저 확인합니다. 다음의 예를 들어보도록 하겠습니다.

public int Divide(int a, int b, out int z)
{
    z = 0;

    if (b != 0)
    {
        z = a % b;
        return a / b;
    }
    else
    {
        throw new DivideByZeroException();
    }
}

무난한 코드입니다. 하지만, 제가 볼 때에는 중괄호를 여닫을 필요가 없어보이는 코드입니다. 아래와 같이 정리하면 어떨까요?

public int Divide(int a, int b, out int z)
{
    z = 0;

    if (b == 0)
        throw new DivideByZeroException();

    z = a % b;
    return a / b;
}

요지는 이렇습니다. 이 메서드에서 우려하는 최악의 상황은 사실 매개 변수 b가 0으로 들어오는 경우입니다. 확실히 문제가 있음을 제기해야 한다면 이 경우를 따로 다루어야 하겠지요. 이를 위해서 b가 0으로 지정되었는지를 검사하여 메서드의 시선으로부터 그런 상황을 제거합니다. 그러면 남는 일은 오로지 나눗셈에 의한 나머지와 몫을 구하는 일이 됩니다. (참고로 z = 0을 서두에 지정한 것은 out 매개 변수에 대한 제약 때문에 그렇습니다. 메서드 본문 밖을 return에 의해서이든 throw에 의해서이든 빠져나가기 전에 반드시 out 매개 변수의 값은 초기화를 해야 합니다.)

그리고 중괄호를 많이 열게 될 개연성이 있는 또 다른 유형은 바로 IDisposable 변수를 다루기 위한 using 블럭입니다. 아래의 경우를 살펴보도록 하겠습니다.

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

using (WinFormModule mod = new WinFormModule(args.FirstOrDefault()))
{
    using (StandardKernel kern = new StandardKernel(mod))
    {
        Application.Run(kern.Get<ApplicationContext>());
        mod.FormName = "Form3";
        Application.Run(kern.Get<ApplicationContext>());
        mod.FormName = "Form2";
        Application.Run(kern.Get<ApplicationContext>());
    }
}

두 번 열 필요가 없어보이는데도 두 번이나 열었습니다. 위의 코드는 아래와 같이 깔끔하게 정리할 수 있습니다.

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

using (WinFormModule mod = new WinFormModule(args.FirstOrDefault()))
using (StandardKernel kern = new StandardKernel(mod))
{
    Application.Run(kern.Get<ApplicationContext>());
    mod.FormName = "Form3";
    Application.Run(kern.Get<ApplicationContext>());
    mod.FormName = "Form2";
    Application.Run(kern.Get<ApplicationContext>());
}

IDisposable.Dispose 메서드가 항상 모든 것을 앗아가기만 하는 것은 아니다.

직전에서 다룬 using과 IDisposable에 대한 흔한 오해는, IDisposable 형식의 참조를 using 문과 함께 사용할 때에는 반드시 using 문 내부에서만 선언해야 한다는 것입니다. 그러나 이 경우 문제가 발생하는 일이 있습니다. 아래의 경우를 살펴보도록 하지요.

using (MemoryStream memStream = new MemoryStream())
using (FileStream fileStream = File.OpenRead(@"WinFormDI.exe.config"))
{
    fileStream.CopyTo(memStream, 64000);
}
// memStream에 들어있는 내용은 어디서 찾을 수 있습니까?

주석 처리한 부분에서 memStream 변수를 접근해야 하는 이유는 간단합니다. 혹시 MemoryStream의 구현 상에 있을지 모르는 버퍼링 (물론 실제로는 그럴리 없습니다만)을 모두 끝내고 실제 스트림에 쓰여진 상태를 확보하고 싶은데, 막상 MemoryStream의 존재 자체를 알 수 없는 외곽 블록에서는 실행이 다 끝나고도 데이터에 접근할 수 없는 우스운 상황이 생깁니다. 위의 코드를 아래와 같이 고치면 의도대로 잘 작동합니다.

MemoryStream memStream;
using (memStream = new MemoryStream())
using (FileStream fileStream = File.OpenRead(@"WinFormDI.exe.config"))
{
    fileStream.CopyTo(memStream, 64000);
}
byte[] buffer = memStream.ToArray();
Console.WriteLine(Convert.ToBase64String(buffer));

사실, 위와 같이 memStream 변수를 밖으로 빼내어도 이상이 없습니다.

memStream은 using 블록 밖에서는 당연히 더 이상 데이터를 기록할 수 없도록 파기된 상태입니다. 하지만, 앞에서 이야기했듯이 IDisposable.Dispose 메서드가 모든 것을 소거하지는 않습니다. 즉, MemoryStream 내부의 byte 배열 버퍼는 여전히 유효합니다. 따라서, 그것의 참조를 Dispose 메서드가 불린 이후라도 가져와서 BASE64 인코딩으로 파일 내용을 인코딩하여 문자열로 바꾸려 했던 코드를 잘 실행할 수 있습니다.

바꾸어 말하면, 아래의 코드도 유효합니다.

MemoryStream memStream = new MemoryStream();
using (memStream)
using (FileStream fileStream = File.OpenRead(@"WinFormDI.exe.config"))
{
    fileStream.CopyTo(memStream, 64000);
}
byte[] buffer = memStream.ToArray();
Console.WriteLine(Convert.ToBase64String(buffer));

객체의 생성을 using 문 밖에서 처리하고, 사용하고픈 참조를 담고 있는 변수명을 지칭하기만 해도 같은 의미가 됩니다. using 문 밖으로 나가면 당연히 memStream은 Dispose 메서드가 호출된 상태가 됩니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2013. 7. 16. 00:00

NuGet Visual Studio에 추가하여 사용할 수 있기도 하고, 독립적으로도 사용할 수 있는 패키지 관리 시스템으로 기존의 Windows Forms 응용프로그램에서부터 ASP.NET, 그리고 Windows 8Windows Phone 8에 이르기까지 다양한 종류의 프로젝트를 지원하는 전천후 패키지 관리 시스템이자 또한 NuGet 웹 사이트와 연동하여 최신의 패키지를 자유롭게 활용할 수 있는 멋진 기능입니다.

.NET Framework 관련 소프트웨어 개발을 시작할 때 새로운 프로젝트를 만들고 TDD 초기 환경 구축을 하는 과정은 다양합니다. Visual Studio가 제공하는 Test Project를 만드는 방법이 있을 수도 있고, 나름대로 Test Mockup을 만드는 방법도 있을 수 있지만, 무료로 사용할 수 있으면서도 분명한 효과를 제공하는 도구로는 단연 NUnit이 거론됩니다. 그런데 Visual Studio의 기본 구성 요소도 아니고, 프로젝트에 추가해서 사용하기 번거로운 면도 일부 있습니다. 그리고 테스트 코드를 만들고 프로젝트에 포함시키는데 있어서도 프로젝트의 코드 관리를 어렵게 만드는 면이 있습니다.

이러한 문제를 해결하기 위한 방법으로 두 가지 방안을 소개하려고 합니다.

첫 번째는, NuGet 패키지 관리자를 이용하여 NUnit Framework는 물론 NUnit RunnerMSI 패키지 설치 방식이 아닌 솔루션 단위의 패키지로 설치하여 버전 관리 시스템에 같이 포함하여 배포할 수 있는 방법에 관한 것입니다. 두 번째는, Friend 어셈블리를 이용하여 테스트 어셈블리에 대해서만 독점적인 접근 권한을 부여하여 테스트 논리를 만드는 절차를 간소화하는 방법에 관한 것입니다.

NuGet 패키지 관리자 버전 확인 후 업데이트하기

NuGet 패키지 관리자는 Visual Studio 2010 이후부터 서비스 팩을 설치하면 극 초기의 버전이 자동으로 추가되는 경우가 있습니다. 하지만 제품과 함께 제공되거나 서비스 팩을 이용하여 설치한 패키지 관리자는 버전이 너무 낮고 기능에도 일부 오류가 있어 쓰기 불편합니다. 당연히 여기에 대한 업데이트가 배포 중이며, 다음과 같은 방법으로 업데이트할 수 있습니다. Visual Studio 2010 이후의 버전은 모두 다음과 같은 방법으로 진행하면 됩니다.

Visual Studio를 시작합니다.

도구 메뉴를 선택한 다음 확장 관리자 메뉴를 아래와 같이 선택합니다.

 

나타나는 대화 상자의 왼쪽 편의 항목들 중 온라인 갤러리선택 후 모두를 선택합니다. 그러면 아래와 같이 NuGet Package Manager가 상위권 항목에 나타납니다. 많이들 사용하는 기능이기 때문에 검색할 필요도 없이 금세 발견할 수 있을 것입니다.

 

업그레이드를 할 필요가 없거나 이미 최신 버전이 설치된 경우 위와 같은 화면이 나타나지만, 대개는 업그레이드가 필요함을 알려줄 것입니다. 리스트에서 다운로드 버튼이 보이면 클릭하여 설치나 업데이트를 진행하시면 됩니다.

설치를 완료한 다음에는 Visual Studio를 다시 시작하라는 메시지가 나타나며, 이 메시지에 따라 다시 시작 버튼을 클릭하면 자동으로 다시 실행됩니다.

기존 프로젝트 또는 새 프로젝트에 NUnit 프레임워크와 NUnit Runner 추가하기

이제 NuGet 패키지 관리자를 새로 업그레이드하였으니 이 패키지 관리자를 사용하여 기존 프로젝트 또는 새 프로젝트에 NUnit 프레임워크와 NUnit Runner를 추가할 차례입니다. 단위 테스트 기능을 추가하려는 프로젝트를 열거나 새로운 프로젝트를 만들고, 아래와 같이 솔루션 탐색기에서 해당 프로젝트를 마우스 오른쪽 버튼으로 클릭한 다음, NuGet 패키지 관리 메뉴를 선택합니다. 만약 테스트 코드와 실제 제품 코드를 분리하고자 할 경우에는 별도의 새로운 프로젝트를 만든 다음 그 프로젝트에 아래 그림과 같이 패키지 관리자를 실행하도록 하면 됩니다.

 

 

그러면 NuGet 패키지 관리자가 다음과 같이 나타납니다. 아무것도 설치한 것이 없으므로 처음에는 덩그러니 빈 화면만 나타나는데, 이번에도 좌측편의 항목들 중 온라인을 선택합니다.

 

그 다음, 우측 상단의 검색 창에 NUnit을 입력하고 검색 버튼을 클릭하면 다음과 같이 NuGet 관련 패키지들이 나타나게 됩니다.

 

이 중에서 우리가 필요로 하는 것은 NUnitNUnit.Runners 패키지입니다. NUnit 패키지에서는 NUnit 프레임워크 어셈블리를 포함하고 있으며, NUnit.Runners 패키지는 NUnit 테스트 실행을 위한 프로그램의 GUI, CLI 및 플랫폼 중립, x86 버전의 파일도 같이 들어있습니다. 그러나 Runners 패키지는 실제 프로젝트에 참조로 추가되는 것은 아니며 Windows 탐색기를 사용하여 파일을 별도로 실행하거나 빌드 자동화 시점에서 활용할 수 있는 유틸리티 정도로 생각하면 편합니다.

이제 새로운 Test Fixture 클래스와 Test Case 메서드들을 몇 가지 추가해봅니다. 테스트해 보고픈 임의의 코드를 추가하고 컴파일이 잘 되는지 확인합니다. 여기서는 다음과 같이 코드를 작성했다고 가정해 보겠습니다.

이제 위의 테스트 어셈블리를 포함한 솔루션을 NuGet이 설치한 NUnit Runner를 통하여 열어보도록 하겠습니다. 솔루션 폴더를 찾아서 폴더 창을 열려고 하면 번거롭습니다. 이를 단순하게 하기 위하여, 현재 열려있는 코드 편집기 창의 탭 부분을 오른쪽 버튼으로 클릭하면 상위 폴더 열기 메뉴가 아래 그림과 같이 나타납니다. 이 메뉴를 클릭합니다.

 

그러면 다음과 같이 폴더 창이 정확한 위치를 가리키며 나타나게 됩니다. 이제 이 위치에서 SLN 파일이 있는 위치로 상위 폴더로 몇 번 이동합니다. 그 다음, 해당 폴더 위치를 기준으로 packages 폴더 > NUnit.Runners.x.x.x 폴더 > tools 폴더 순으로 접근합니다. 그리고 아래 그림과 같이 nunit.exe 파일을 찾아 실행합니다.

 

익숙한 화면이 나타납니다. 시스템에 관리자 권한을 이용하여 설치하지 않았어도 NUnit Runner가 즉시 실행되고 사용 가능한 상태로 준비된 것이 보입니다. 이제 여기서 SLN 파일을 열어보겠습니다. File 메뉴의 Open 메뉴를 선택하여 SLN 파일을 찾아 엽니다.

 

만약 솔루션 파일을 열려고 시도하였을 때, 솔루션이 이상 없이 컴파일이 잘 됨에도 불구하고 다음과 같이 오류 메시지가 나타나면 대상 플랫폼 설정이 NUnit의 대상 플랫폼과 일치하지 않기 때문에 오류가 발생하는 것입니다.

이 경우 문제 해결을 위하여 아래 그림과 같이 대상 플랫폼을 Mixed Platform 대신 x86으로 변경하고 nunit-x86.exe Runner를 대신 사용하거나, Any CPU로 맞추어 다시 솔루션을 빌드합니다.

SLN 파일을 열고 난 다음에는 테스트를 진행할 수 있게 화면이 나타납니다. 현재 활성화된 환경 설정을 기준으로 자동으로 포커스가 변경됩니다.

테스트가 잘 실행되는지 살펴봅니다. 예상대로 Case 1decimal이 정확한 덧셈을 처리하고 있음을 증명하며, Case 2Windows 환경에서 언제나 성공합니다. 그러나 Case 3Windows 환경에서 언제나 실패하며, Case 41글자이지만 StringChar가 분명히 다른 형식임을 확인해주고 있습니다.

실제 코드 어셈블리와 테스트 어셈블리를 분할하는 방법

NuGet 패키지 관리자를 사용하여 NUnit을 전보다 더 가깝고 편리하게 사용할 수 있게 된 것은 좋은 일입니다. 그렇지만 한 가지 고민이 남는데, 인프라의 개선과는 별도로 설계와 유지에 있어서 테스트 코드와 실제 제품 코드가 한 배를 타는 것은 별로 좋은 것 같지 않습니다. 테스트 코드가 제품 코드에 자유롭게 접근할 수 있으면서도, 제품 코드가 테스트 코드를 배려하는 별도의 부수적인 옵션 구성 요소들을 추가하는 일 없이, 테스트 코드가 자유롭게 제품의 기능을 접근하여 확인할 수 있는 수단이 필요할 것입니다.

여기에 대한 답을 .NET FrameworkFriend Assembly라는 이름의 개념으로 정의하고 있는데, 기본적으로 Assembly는 그 안에 속한 Module들 간에는 internal로 선언한 멤버들을 자유롭게 제어하고 다룰 수 있게 되어있습니다. 그런데 이 Assembly 간의 관계를 설정해두면 특정 어셈블리 상의 코드에 대해서만 internal로 선언한 멤버들을 자유롭게 제어하고 호출하거나 다룰 수 있게 해주는 특권의 부여가 가능합니다.

이 기능을 사용하면, 제품에 대한 실제 코드를 담고 있는 클래스 라이브러리나 실행 파일 모듈을 가지고 있는 .NET 어셈블리와 각 유형별 테스트 케이스를 따로 모아놓은 테스트 어셈블리들을 분리하여 테스트 어셈블리는 배포하지 않고, 실제 코드 어셈블리만 배포하는 것이 가능합니다. 그러면서도, 실제 코드 어셈블리의 모든 internal 멤버들을 테스트 어셈블리들이 자유롭게 활용할 수 있습니다. 이렇게 하여 둘 사이에 발생할 수 있는 상호 종속적인 관계를 분리할 수 있으니 훨씬 자유로운 테스트 코드 작성이 가능합니다.

위의 예제에서 보인 것처럼 실제 코드와 테스트 코드를 분리한 상태에서, 실제 코드를 가지고 있는 어셈블리에서는 우선 보호하고 싶은 클래스나 멤버에 대해 internal 키워드를 사용하여 선언합니다. 여기까지는 우리가 알고 있는 그대로이며, 다른 어셈블리에서는 internal 키워드를 사용하여 선언한 멤버들을 접근하거나 활용할 수 없습니다. 그러나, 프로젝트 내에 추가할 테스트 어셈블리의 이름을 아래 그림과 같이 확인해둡니다.

접근을 허용하려는 테스트 어셈블리의 이름을 찾아 복사합니다. 그리고 실제 코드를 포함하는 어셈블리의 적당한 위치에 다음과 같이 코드를 작성합니다. 아래와 같이 어셈블리에 대한 특성을 부여하는 코드는 보통 Visual Studio 프로젝트와 함께 자동으로 생성되는 AssemblyInfo.cs 파일에 기술하면 편리합니다.

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("<Assembly Name>")]

 

위와 같이 코드를 작성하고 컴파일 한 다음 경고 메시지가 나타나지 않으면 됩니다. 그 다음, 접근을 허용한 어셈블리에서 테스트하려는 코드를 포함한 어셈블리를 참조에 추가한 다음, internal로 선언한 모든 멤버들을 정상적으로 사용할 수 있는지 확인하여, 테스트 코드를 작성할 수 있는 상태이면 테스트 케이스를 만들어나가기 시작하면 됩니다.

결론

테스트 주도 개발은 이번 아티클에서 살펴본 것과 같이 초기의 개발 환경 구축을 단순화할 수 있다면 얼마든지 쉽게 시작할 수 있는 효율적이고 인상적인 개발 방법론입니다. 그러나 여기에서 염두에 두어야 할 것은 이렇게 구축한 개발 환경을 어떤 관점을 유지하면서 활용해 나아갈 것인가에 대한 전략의 설정과 실천에 있을 것입니다.

테스트 주도 개발에 관한 좀 더 근본적인 내용을 검토하기 위해서는 다양한 자료들을 참조할 수 있지만, 가장 추천해 드릴 만한 자료로는 단연 Kent BeckTest Driven Development (ISBN 978-89-91268-04-3)이라는 도서입니다. 테스트 주도 개발의 원칙과 방향성에 대한 이야기를 자세히 들어볼 수 있으므로 꼭 살펴보실 것을 권합니다.


Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2013. 2. 3. 21:28

C#과 VB.NET을 이용해서 IDisposable 객체를 다룰 경우, 할당과 해제를 짧은 기간 내에 완벽하게 관리하기 위해서 using 구문을 활용하는 일이 자주 있습니다. 그러나 using 구문의 경우 스코프를 정확하게 다루기 위해서 중괄호나 구문 구조 상 Indent를 하게 되어있습니다. 쓰는 것 자체는 일은 아니지만 using 문이 여러번 사용되다보면 코드에 지나치게 많은 Indent가 쓰이게되서 보기 어려운 코드가 될 수 있습니다. 이를 해결하는 방법을 소개합니다.

Note: 아래에서 소개하는 예제 형식들은 IDisposable 인터페이스를 구현하는 임의의 객체라고 가정하겠습니다.

C#에서 using 구문을 간단하게 사용하는 방법

using (Sample a = new Sample())
{
    using (Sample b = new Sample())
    {
        using (Sample c = new Sample())
        {
            // Sample code goes here...
        }
    }
}

위와 같은 코드가 있습니다. 변수 세 개를 선언했을 뿐이지만 중괄호가 세 번이나 열리고 닫힙니다. 당연히 보기 좋을리 없습니다. 어떻게 정리하면 좋을까요?

using (Sample a = new Sample())
using (Sample b = new Sample())
using (Sample c = new Sample())
{
    // Sample code goes here...
}

앞의 코드보다 훨씬 간결해졌습니다. 연달아오는 세 개의 using 문 안에 선언된 변수는 같은 Scope로 분류되어 뒤이어 오는 중괄호 섹션 한 번 안에 한꺼번에 변수의 수명 주기가 관리됩니다.

그리고 또 다른 방법이 있습니다. 만약, 다루어야 될 IDisposable 객체가 모두 같은 형식이거나 상속 관계 상 활용 가능한 수준의 공통의 부모 클래스나 인터페이스를 가지는 경우 아래와 같은 기술법도 가능합니다.

using (Sample
    a = new Sample(),
    b = new Sample(),
    c = new Sample())
{
    // Sample code goes here...
}

위의 예제는 특히 System.IO.Stream 클래스를 기반으로 할 경우 매우 유용합니다. 입출력 작업에 관련된 기본적인 동작이 이미 System.IO.Stream 클래스에서 구현되어있으므로 특수한 경우를 제외하면 위의 구문을 이용하여 간편하게 코드를 정리할 수 있기 때문입니다.

VB.NET에서 Using 구문을 간단하게 사용하는 방법

C#과 마찬가지로 VB.NET 또한 Using 구문을 간단하게 정리할 방법이 있습니다. 아래와 같은 코드가 있다고 가정하겠습니다.

Using A As Sample = New Sample()
    Using B As Sample = New Sample()
        Using C As Sample = New Sample()
            ' Sample code goes here...
        End Using
    End Using
End Using

Indent가 세 번이나 들어갑니다. 거기에다 C#처럼 같은 줄에 Using 구문을 몰아서 쓸 수 있는 것도 아닌것 같습니다. 방법이 있을까요? 아래와 같이 정리하면 됩니다.

Using A As Sample = New Sample(), _
    B As Sample = New Sample(), _
    C As Sample = New Sample()
    ' Sample code goes here...
End Using

Comma 기호를 이용하여 서로 다른 여러 IDisposable 구현 객체를 한 번에 초기화할 수 있습니다. 여기서 주의하실 것은, C#과 달리 VB.NET은 개행 문자에 대해 이스케이프 처리가 필요하며, 언더스코어 (_) 기호 앞에는 하나 이상의 Whitespace (0x20) 문자가 들어와야하고, 언더스코어 기호 뒤에는 다른 문자를 절대 쓰지 말고 바로 Enter 키를 눌러 개행 문자를 지정하도록 해야 올바르게 줄 이어쓰기로 해석됩니다.

정적 메서드를 이용하여 초기화 과정을 캡슐화하기

위와 같은 구문을 어디에서나 사용할 수 있다면 편리하겠지만, 불가피하게 생성자 이외에 부수적인 초기화 작업이 따르는 경우도 많습니다. 대표적으로 ADO.NET이 그러한 예인데, 여러분만의 독자적인 Helper Library Class를 만들어서 호출하는 방법으로 객체를 생성한다면 위의 코드를 응용할 수 있으므로 여러 IDisposable 인터페이스 구현체를 같은 스코프 안에서 한번에 할당하고 해제하는 구성을 시도할 수 있습니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2013. 1. 2. 14:44

안녕하세요. Windows Azure MVP 남정현입니다. 이번에 살펴볼 내용은 비동기 프로그래밍에서 중요한 컨셉 중 하나인 스레드 동기화에 약방의 감초처럼 쓰이는 AutoResetEvent와 ManualResetEvent에 대해 간단한 포스팅을 준비해보았습니다. 알아두시면 유용하게 활용할 수 있을 것입니다.

StackOverflow에 있는 글을 읽어보다 재미있는 내용이 있어서 Facebook에도 포스팅을 했었습니다.

정말 알기쉽고 명료하게 비유한 글이군요. ManualResetEvent는 수동문이고 AutoResetEvent는 지하철 개찰구 내지는 자동문과 같지요. :-)

Yes. It's like the difference between a tollbooth and a door. The ManualResetEvent is the door, which needs to be closed (reset). The AutoResetEvent is a tollbooth, allowing one car to go by and automatically closing before the next one can get through.

출처: http://stackoverflow.com/questions/153877/what-is-the-difference-between-manualresetevent-and-autoresetevent-in-net

그런데 정말로 그런지 알아보고 싶어서 샘플 코드를 멋대로 만들어보았습니다. 다중 스레드나 이런게 아니라 그냥 단일 스레드 상에서도 차이점이 나타나는지 알아보고 싶었는데, 확실히 특징이 보였습니다. 아래의 샘플 코드가 그렇습니다.

키보드의 M키를 눌러서 시작하면 ManualResetEvent를 사용하여 로직을 실행하는데, 이러한 경우 처음에 Set Flag가 켜진 상태 (Set 호출)에서 WaitOne 메서드를 4번 호출하게 되는데 Flag가 켜진 상태이므로 대기하지 않고 매번 호출이 빠져 나가게 됩니다. 그러나 Reset을 호출하여 Set Flag를 끈 상태에서는 WaitOne 메서드에 지정한 대기 시간만큼 실제로 대기하게됩니다.

반면 AutoResetEvent는 Set을 처음 한번 호출했을 때만 WaitOne 메서드가 무시되고 그다음부터는 계속 WaitOne 메서드에 지정한 대기 시간만큼 실제로 대기하게 됩니다. 앞서 설명했던 것 처럼 Set 메서드를 부르고 나서 이후에 벌어지는 일에 차이가 있는 셈입니다.

AutoResetEvent의 Auto란 즉, 자동으로 Reset을 호출한다는 의미이므로 비유에서처럼 톨 부스, 지하철 개찰구같은 아날로지에 대응이 가능한 것이고, ManualResetEvent의 Manual이란 방문을 열어놓고 직접 밀어서 닫지 않는 한 문이 계속 열려있는 상태의 아날로지에 대응이 가능한 것입니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

기술 소식2012. 11. 1. 23:14

안녕하세요. Windows Azure MVP 남정현입니다. 이번 BUILD 2012에서는 Windows 8과 Windows Server 2012를 필두로 하는 다양한 업데이트 소식이 있었는데요, 한 번에 알아보기 쉽도록, 그리고 약간의 시차를 두고 있는 흥미로운 새 소식들도 같이 전해드릴까 합니다.

Windows Server 2012 및 .NET Framework 4.5 지원 추가

Visual Studio 2012 출시와 함께 Windows Server 2012, .NET Framework 4.5에 대한 지원이 새로 추가되었습니다. 그리고 ASP.NET의 경우 ASP.NET MVC 4.0 업데이트를 포함하고 있고, C# 5.0 및 VB 11.0에 대한 지원도 포함하여 멀티 스레드 프로그래밍을 좀 더 생산성있게 할 수 있는 방안을 대폭 마련하고 있습니다. .NET Framework 4.5에서 향상된 내용들은 http://msdn.microsoft.com/ko-kr/library/ms171868.aspx 에서 확인하실 수 있습니다.

Windows Azure Mobile Service의 Windows Phone 8 지원 추가

Windows Phone 8 SDK 발표와 함께 Windows Azure Mobile Service에서 Windows Phone 8 대상 SDK도 같이 발표하였습니다. Windows 8과 Windows Phone 8을 위한 App 모두를 지원하는 것이므로 N 스크린 앱 개발에 큰 도움이 될 것입니다. 자세한 튜토리얼은 https://www.windowsazure.com/en-us/develop/mobile/tutorials/get-started-wp8/ 에서 확인하실 수 있습니다.

Windows Azure Store 런칭

Windows Azure 2012년 초반 업데이트에 공개된 적이 있었던 ClearDB의 Azure 기반 MySQL 데이터베이스 서비스는 이미 잘 알려져 있습니다. 그런데 한 가지 아쉬웠던 점이 있었다면 무료 서비스에 한정되어있었던데다 Windows Azure와는 따로 떨어져있는, 접근성이 그다지 좋지 않은 부가 서비스였었습니다. 그러나 이제는 ClearDB의 사례를 포함하여 Windows Azure 서비스에 결합할 수 있는 다양한 컴패니언 서비스 및 데이터 소스를 한 곳에서 쉽게 구매하고 자원으로 관리할 수 있도록 Windows Azure Store 안에서 통합 관리할 수 있게 되었습니다. 아쉽게도 2012년 11월 현재 미국에서만 런칭이 된 상태입니다만 조만간 한국에서도 편리하게 대량 E-MAIL 발송, 대용량 MySQL 데이터베이스 등 다양한 서비스를 쉽게 구매해서 실제 클라우드 서비스에 반영할 수 있을 것입니다. 자세한 내용은 https://www.windowsazure.com/en-us/store/overview/ 에서 살펴보실 수 있습니다.

새 버전의 .NET용 Windows Azure SDK 및 가이드 런칭

.NET용 Windows Azure SDK의 새 버전이 발표되었습니다. 다른 써드파티의 Windows Azure 관련 도구와 비슷하게 동작하도록 개선되고 향상된 Visual Studio Add-in을 대거 포함하며, 새롭게 설계된 클래스 라이브러리 및 .NET Framework 4.5 타겟팅을 지원합니다. 자세한 내용은 http://msdn.microsoft.com/en-us/library/ff683673.aspx#BK_October2012 에서 확인하실 수 있습니다.

Windows Azure 분산 캐시 정식 업데이트

AppFabric Cache로 소개되었던 적이 있는 이전 버전의 캐시는 매우 가격이 비쌌고 이에 비해 얻을 수 있는 득이 그렇게 크지 않았었습니다. 이를 대체하여 좀 더 사용자에게 실질적인 캐시 서비스의 이점을 누릴 수 있게 하기 위하여 새롭게 분산 캐시를 업데이트하였는데, 이번 릴리즈에서 정식 서비스로 업데이트되었습니다. Web Role이나 Worker Role, 혹은 Cache 전용 Worker Role을 만들어서 상황에 따라 유동적으로 증감하는 고성능 분산 캐시를 쉽게 구축할 수 있게 되었습니다. 이에 대한 자세한 내용은 https://www.windowsazure.com/en-us/home/features/caching/ 에서 살펴보실 수 있습니다.

Visual Studio Team Foundation Service Online 정식 런칭

Visual Studio TFS Online 또한 정식으로 서비스가 런칭되었습니다. 2012년 11월 현재 무료 버전으로만 서비스가 운영되고 5명의 사용자까지 지원합니다. Visual Studio, Eclipse, XCode와 함께 연동할 수 있도록 다양한 애드인과 함께 배포되며, Windows Azure Web Site 서비스와 함께 연동할 수 있으므로 다양한 요구 사항을 충족할 수 있습니다. 그리고 Git을 이용하여 TFS를 대상으로 작업할 수 있는 도구인 Git-TF (코드프로젝트 홈페이지: http://gittf.codeplex.com/, Microsoft 다운로드 페이지 주소: http://www.microsoft.com/en-us/download/details.aspx?id=30474)도 같이 활용하시면 유용하실 것입니다. http://blogs.msdn.com/b/somasegar/archive/2012/10/31/team-foundation-service-is-released.aspx 에서 자세한 내용을 보실 수 있으며, 서비스 사용은 http://tfs.visualstudio.com/ 에서 신청 가능합니다.

Windows Azure SQL Data Sync 10월 업데이트

오랜 기간에 걸쳐서 평가를 진행 중인 Windows Azure SQL Data Sync 서비스가 이번 10월 업데이트를 기준으로 전세계 모든 데이터센터에서 사용 가능하도록 배포가 완료되었습니다. Windows Azure SQL Data Sync 서비스를 사용하면 기존 SQL 서버 데이터베이스 간, Windows Azure SQL Database 간, 혹은 기존 SQL 데이터베이스와 Windows Azure SQL Database 사이의 데이터 동기화를 비동기적으로 최소한의 코드 작성을 통하여 손쉽게 수행할 수 있는 것이 특징이며 이에 대한 자세한 내용이 문서화되어있습니다. SQL Data Sync 서비스에 대한 소개는 http://msdn.microsoft.com/ko-kr/library/hh456371 페이지를, SQL Data Sync 서비스에 대한 시행착오를 최소화하기 위한 가이드는 http://msdn.microsoft.com/ko-kr/library/hh667328.aspx 페이지의 내용을 참고하시면 유용합니다.

Windows Azure 기술 운영에 관한 중국의 21Vianet社와의 MOU 체결

Windows Azure는 Public Cloud Computing Service로, 그동안 중국 내에서는 해외 데이터센터의 이용이 쉽지 않았던 비즈니스 상의 특성 때문에 Windows Azure가 서비스를 할 수 없었던 대표적인 국가였습니다. 이러한 한계를 극복하기 위해서 21Vianet社 (http://www.en.21vianet.com/)와의 MOU를 체결하여 Windows Azure 운영 시스템을 중국 내 로컬 데이터센터에서 이용할 수 있도록 협약을 맺었다는 소식이 Windows Azure 공식 블로그를 통해서 공개되었습니다. ( http://blogs.msdn.com/b/windowsazure/archive/2012/11/01/cloud-os-is-coming-to-china.aspx) 중국 내에서 클라우드 컴퓨팅 서비스를 도입할 것을 계획 중이신 경우 향후 21Vianet을 통하여 Windows Azure와 유사한 서비스를 중국 내 로컬 데이터센터를 이용하여 경험할 수 있을 것입니다.


Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

기술 소식2012. 10. 29. 02:06

오랜 기간을 거쳐 Mono가 드디어 3.0 버전에 진입하였습니다. 여러가지 악재가 있었음에도 포기하지 않고 지속적으로 Mono 프로젝트를 이끌어나가시는 여러 개발자분들의 노고에 응원을 드리며 즐겁게 블로그 포스팅을 올립니다. 이번 Mono 릴리즈는 다른때보다도 더 의미가 깊고 강렬합니다. 무엇보다도, Windows Azure를 포함하여 국내외 여러 클라우드 컴퓨팅 환경 상에서 Mono를 다양하게 활용할 수 있다는 것은 바람직한 일이라고 할 수 있겠습니다. 특히 서버 사이드에서의 .NET 기반 개발 환경은 더 이상 Windows에만 국한되는 것이 아닙니다.

Mono 3.0은 Mono 2.10 브랜치를 계승하는 메이저 업데이트로 다음의 주요 변경 사항들을 포함합니다. 정보의 출처는 공식 릴리즈 노트 (http://www.mono-project.com/Release_Notes_Mono_3.0) 입니다.

비동기 프로그래밍 모델을 지원하는 새 C# 컴파일러

비동기 프로그래밍 모델의 원형은 .NET 4.0의 소개와 함께 TPL (Task Parallel Library)로 이미 소개된 이력이 있습니다만 이것을 C# 4.0의 다음 세대 언어인 C# 5.0에서 언어 차원에서 자연스럽게 통합하기 위한 노력이 있었는데 이것이 Mono 3.0의 C# 컴파일러부터 온전하게 지원됩니다. 즉, async~await 키워드의 사용이 가능해져서 좀 더 자연스럽게 비동기 프로그래밍의 이점을 여러 플랫폼으로 확장할 수 있게 됨을 뜻합니다.

복잡하고 정신없던 컴파일러 별칭의 구조 조정

오픈 소스의 특성상, 그리고 여러 플랫폼을 동시에 지원해야 했기 때문에 긴 시간 동안 고수되어왔던 컴파일러 별칭의 혼재가 드디어 정리됩니다. mcs라는 단일 컴파일러 유닛으로 정리되고 -sdk 플래그를 사용하여 특정 프로필을 목표로 컴파일 방법 및 라이브러리를 정의할 수 있습니다. 그리고 이와 동시에 특정 프레임워크의 버전의 영향을 받지 않는 IKVM.Reflection 기반의 코드 생성 체계로 변경되어 더욱 유연하고 단순한 Code Emitter를 만들어 컴파일러를 단순화한 것이 큰 변화입니다.

개선된 Evaluator API

Mono의 유용한 명령줄 도구인 C# Interactive Shell의 핵심인 Evaluator 클래스의 Eval 메서드에서 이제는 단순 표현식이 아니라 각종 Type (Class, Structure, Interface, Delegate, Namespace)들을 직접 명령문 세그먼트에서 해석하고 처리할 수 있도록 기능이 확장되어 더 강력한 코드 작성이 가능해졌습니다. 그리고 Evaluator 클래스는 이제 싱글턴이 아니라 인스턴스화가 가능한 유틸리티로 기능이 개선되어 단일 코드에서 다중 컴파일러를 사용할 수 있는 막강한 확장성을 보유하게 되었습니다.

Microsoft 기술과의 호환성 향상

.NET Framework 4.5의 출시에 따라 Microsoft 기술과의 차이가 생기는 부분이 있었는데, 이 부분에 대해 적극적으로 지원을 하게 되어 아래와 같은 부분에서 확실한 호환성을 기대할 수 있습니다.

  • 새로운 비동기 메서드
  • WinRT 호환 API
  • System.Net.Http
  • System.Net.Http.Formatting
  • System.Thrading.Tasks.Dataflow
  • System.Web.Http
  • System.Web.Razor (Razor 문법 지원)
  • System.Web.WebPages (ASP.NET Web Pages 2 지원)
  • System.Web.WebPages.Deployment
  • System.Web.WebPages.Razor (ASP.NET Web Pages 2 Razor 지원)
  • System.Web.Mvc.dll (ASP.NET MVC4 지원)
  • System.Json.dll (Microsoft 구현으로 대체)
  • EntityFramework.dll

향상된 가비지 컬렉터

가비지 컬렉터의 새 구현체인 SGen이 좀 더 전면에 적극적으로 등장하고 활용 폭도 넓어졌습니다. 이전에 사용하던 Boehm GC를 대체하는 것으로 다중 프로세서 지원, Win32 지원, MIPS 지원, Mac OS X 환경에서 Mach API와 직접 연동을 통한 성능 향상 등 장족의 발전이 있었고 이번 3.0 릴리즈에서 크게 활약할 것으로 보입니다.

그 외 개선된 사항들

  • 리눅스에서 System.Net.NetworkInformation.NetworkChanged 사용 가능
  • 유니코드 지원 개선 및 성능 향상
  • ThreadLocal<T> 성능 향상, List<T> 성능 향상
  • Mac OS X에서 System.IO.DriveInfo를 올바르게 사용할 수 있음
  • Mono.Data.Sqlite에서 스레딩 모델 설정 가능 및 iOS의 암호화 API 지원

좀 더 자세한 정보는 http://www.mono-project.com/Release_Notes_Mono_3.0 에서 확인해보실 수 있습니다. 이 글을 쓰는 시점에서는 Mac OS X 패키지만 공개되었지만 2012년 11월 중으로 Windows와 Linux에서도 사용 가능한 패키지가 빌드될 것으로 보입니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2012. 10. 26. 00:42

안녕하세요. Windows Azure MVP 남정현입니다.

오늘 소개해드리려고 하는 내용은 ClickOnce용 패키지를 만들었을 때 유용하게 활용하실 수 있는 팁입니다. 보통은 같이 만들어지는 setup.exe 프로그램을 통해서 ClickOnce 패키지가 시작되도록 배포하는 것이 일반적이겠지만, 이 setup.exe를 대신하여 여러분만의 고유한 Bootstrapper를 제작할 수 있는 방법이 있습니다. 바로 ClickOnce의 주요 핵심 DLL인 DFSHIM.DLL 파일의 API 2개를 활용하는 것인데요, 지금 소개하려는 API를 보통은 rundll32.exe 프로그램을 이용해서 호출하는 것으로만 구글의 검색 결과에 보통 열거됩니다. 그러나 이 기능을 rundll32.exe 프로그램에 의존하지 않고 직접 프로그래밍 코드에서 호출할 수 있는 방법은 없을까요?

rundll32.exe로 호출하는 API에 대한 특성 이해하기

rundll32.exe 프로그램은 약간의 트릭과 암묵적인 규칙을 기반으로 동작하는 시스템 유틸리티로 다소 게으른(?) 면이 있습니다. 특수한 경우를 제외하고 일반적으로 DLL 파일은 직접 실행할 수 없고 반드시 다른 EXE 파일에 동적이든 정적이든 링크되어 사용되야만 합니다. 프로그램 개발 공수 관점에서 보면 DLL에 중요 컨텐츠를 포함시켜놓았을 경우 번번히 이런 컨텐츠를 위해서 별 의미없는 EXE 파일을 빌드해야 하는 셈인데, 이러한 낭비적 요소를 제거하기 위해서 일반화된 DLL 호스트 및 실행 프로그램을 넣게 됩니다. 그러나 잘 아시겠지만, 사실 이는 잠재적으로 보안 위협이 되는 부분도 있습니다.

다행히도 rundll32.exe는 무분별, 무절제하게 아무렇게나 들어오는 입력을 모두 받아들이는 것이 아닙니다. 이에 대한 상세한 규칙은 Microsoft KB164787 문서 (http://support.microsoft.com/kb/164787) 에 상세하게 기록되어있으며 내용을 요약하면, RUNDLL32.EXE로 호출할 수 있는 함수 시그니처는 대강 아래와 같은 형태로 제약됩니다.

  • void __stdcall <Function>W(HWND hwnd, HINSTANCE hinst, LPCWSTR lpszCmdLine, int nCmdShow);
  • void __stdcall <Function>(HWND hwnd, HINSTANCE hinst, LPCSTR lpszCmdLine, int nCmdShow);
  • void __stdcall <Function>(void);

이 글을 작성하는 현 시점에서 16비트 운영 체제는 일상적으로 사용되지 않고, 32비트 및 호환 운영 체제 가운데에서도 NT 커널을 계승하는 운영 체제가 주로 사용됨을 감안하였을 때, 보통 위와 같이 시그니처들이 있다고 볼 수 있습니다. W라는 접미사가 붙는 것은 세 번째 매개 변수가 문자열 버퍼를 포함하고 있기 때문에 적용되는 Windows 프로그래밍 환경에서의 Convention입니다. 이와 같이 Wide String을 지원하는 함수가 있다면 가장 적극적으로 먼저 쓰이게 됩니다. 그리고 해당되는 함수가 없다면 Ansi String을 지원하는 두 번째 후보가 차선책으로 쓰이게 됩니다. 만약 별도의 파라미터가 없이 불린다면 세 번째 시그니처에 해당되는 함수가 채택됩니다.

DFSHIM.DLL의 문서화되지 않은 API 두 가지

DFSHIM.DLL은 .NET Framework 2.0과 함께 배포되는 ClickOnce의 핵심 기능을 포함하는데, 확장자가 .application인 파일을 실행해주거나 ClickOnce와 직접 확장자를 연결시킬 경우 연결 프로그램으로서 실행해주는 등의 기능, 그리고 ClickOnce 캐시 저장소 초기화 등의 기능을 담당합니다. 인터넷 자료를 검색해보면 대개는 COM 기반의 API나 제한된 몇 종류의 API만을 이야기하는 것으로 이야기가 잘 보입니다.

그러나 공식적으로 사용되면서도 정확하게 문서화되어있지 않은 API가 두 종류가 있으며 사실은 더 사용하기 쉬운 API가 두 종류가 있습니다. 바로 ShOpenVerbApplication(W), CleanOnlineAppCache에 관한 것인데, 양쪽 모두 rundll32.exe로 실행하는 방법은 아래와 같다고 나오지만 실제 프로그래밍 언어에서 다루는 방법에 대한 문서가 거의 없습니다.

  • %windir%\system32\rundll32.exe dfshim.dll,ShOpenVerbApplication <.application 파일의 경로나 URL>
  • %windir%\system32\rundll32.exe dfshim.dll,CleanOnlineAppCache

위와 같이 실행하는 방법 말고 더 간단한 방법은 없을까요? 앞에서 소개한 내용을 바탕으로 시그니처를 대입하면서 맞추어보니 아래와 같이 정의할 수 있었습니다.

  • typedef void (WINAPI *ShOpenVerbApplicationWProc)(IN HWND, IN HINSTANCE, IN LPCWSTR, IN int);
  • typedef void (WINAPI *ShOpenVerbApplicationAProc)(IN HWND, IN HINSTANCE, IN LPCSTR, IN int);
  • typedef void (WINAPI *CleanOnlineAppCacheProc)(VOID);

위의 함수 포인터에 대한 선언을 활용하여 _UNICODE 매크로 선언 여부에 따라 동적으로, 그리고 선택적으로 호출할 수 있도록 만들 수 있었습니다. (Visual C++ 컴파일러 기준)

// 함수 포인터 선언
typedef void (WINAPI *ShOpenVerbApplicationWProc)(IN HWND, IN HINSTANCE, IN LPCWSTR, IN int);
typedef void (WINAPI *ShOpenVerbApplicationAProc)(IN HWND, IN HINSTANCE, IN LPCSTR, IN int);
typedef void (WINAPI *CleanOnlineAppCacheProc)(VOID);
// 조건부 매크로 선언
#ifdef _UNICODE
 #define ShOpenVerbApplicationProc ShOpenVerbApplicationWProc
 #define ShOpenVerbApplicationName "ShOpenVerbApplicationW"
#else // _UNICODE
 #define ShOpenVerbApplicationProc ShOpenVerbApplicationAProc
 #define ShOpenVerbApplicationName "ShOpenVerbApplication"
#endif // _UNICODE
// 변수 선언
 HINSTANCE hLibrary;
 ShOpenVerbApplicationProc pProc;
 CleanOnlineAppCacheProc pClearProc;
 // DLL 로드 시도 및 함수 검색 (DLL 로드에 실패한 경우 .NET Framework 설치를 유도할 수 이
 BOOL LoadDFSHIM(void) {
  hLibrary = LoadLibrary(_T("DFSHIM.DLL"));

  if (hLibrary == NULL)
   return FALSE;

  pProc = (ShOpenVerbApplicationWProc)GetProcAddress(
   hLibrary,
   ShOpenVerbApplicationName);

  pClearProc = (CleanOnlineAppCacheProc)GetProcAddress(
   hLibrary,
   "CleanOnlineAppCache");

  if (pProc == NULL || pClearProc == NULL) {
   pProc = NULL;
   pClearProc = NULL;
   FreeLibrary(hLibrary);
   return FALSE;
  }

  return TRUE;
 }
 // 프로그램 종료 시 호출하여 자원 할당을 해제
 VOID UnloadDFSHIM(void) {
  if (pProc)
   pProc = NULL;

  if (pClearProc)
   pClearProc = NULL;

  if (hLibrary)
  {
   FreeLibrary(hLibrary);
   hLibrary = NULL;
  }
 }
// ClickOnce application 시작 시 호출
if (this->hLibrary != NULL && this->pProc != NULL)
{
  this->pProc(NULL, NULL, _T("ClickOnce .application 파일 경로 또는 URL"), SW_SHOW);
}
// 기존 Online 전용 App의 Cache를 삭제할 때 호출 (설치 시 문제가 있을 경우 활용 가능)
if (this->hLibrary != NULL && this->pClearProc != NULL)
{
  this->pClearProc();
}

위와 같이 C/C++ Application에서 간단하게 ClickOnce Online App 및 Offline App 설치를 호출할 수 있고, Online App Cache를 초기화할 수 있습니다.

결론

Windows Desktop App 가운데에서도 .NET으로 배포하는 App의 경우 설치 도입부부터 특별한 사용자 경험을 제공하기 위한 목적으로 위의 기능을 활용하면, setup.exe 파일 대신 여러분이 직접 디자인한 Setup Bootstrapper를 만들어 배포할 수 있고, 혹은 rundll32.exe 프로그램을 그대로 이용하여 바로가기 아이콘을 만드는데 활용할 수도 있습니다.

이 글에 대한 프리뷰 이미지 출처: http://hummingbird.tistory.com/3614

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2012. 10. 8. 21:36

안녕하세요. Windows Azure MVP 남정현입니다.

오늘 소개하려는 내용은 개발자분들께 매우 유용한 팁이 될 것 같습니다. 요즈음에도 디자이너와 개발자 사이에는 협업을 하기 쉽지 않은 점들이 매우 많습니다. 특히 디자이너가 공들여 작업한 PSD 파일은 막상 개발자의 손에 떨어지면 아무 의미 없는 바이너리 파일이 되기 쉽습니다. 종국에는 개발자가 디자이너의 따가운 눈초리를 애써 무시하면서 레이어 파일들을 일일이 잘라달라고 부탁하지 않으면 안되는 상황이 되곤 하지요. :-)

그러나 이러한 수고스러운 작업을 디자이너에게 요구하지 않고 개발자 스스로 PSD 파일을 레이어 별로 낱개의 투명 PNG 파일로 만들 수 있는 일련의 방법을 찾았습니다. 이를 위하여 Photoshop을 설치하거나 별도의 상용 유틸리티를 써야 하는 것은 더더욱 아니며 온전히 인터넷 상에서 구할 수 있는 도구와 플러그인, 그리고 Paint.net의 힘으로 도달할 수 있는 방법이므로 나름 추천해드릴만 하다고 생각합니다.

1단계: Paint.net 설치하기

Paint.net은 Rick Brewster가 개발한 프리웨어 기반의 Raster Graphic Editor 소프트웨어로 초창기에는 오픈 소스였지만 현재는 프리웨어로 전환한, C#으로 만든 멋진 그래픽 도구입니다. GIMP나 Photoshop을 대체하면서 Windows 환경에서 빠르고 가볍게 사용할 수 있는 그래픽 도구로 널리 알려져 있고 국내에서도 인지도가 제법 높은 편입니다.

Paint.NET은 http://www.getpaint.net/ 에서 최신 버전을 설치할 수 있습니다.

2단계: Paint.net PSD 플러그인 설치하기

Paint.net은 훌륭한 그래픽 편집 도구이지만 PSD를 직접 지원하지는 못합니다. 대신 PDN이라는 자체 파일 형식을 사용하기 때문에 Paint.net만 설치해서는 PSD 파일을 다룰 수 없습니다. 이를 극복하기 위하여 Paint.net PSD 플러그인을 http://psdplugin.codeplex.com/ 에서 최신 버전을 다운로드하고 설치해야합니다. 플러그인 ZIP 파일을 다운로드하면 PhotoShop.dll 파일을 확인할 수 있으며 이 파일을 아래와 같이 설치합니다.

  • 실행 중인 Paint.net 프로그램을 모두 종료합니다.
  • PhotoShop.dll 파일을 %PROGRAMFILES%\Paint.NET\FileTypes 폴더 아래에 복사합니다.
  • 다시 Paint.net을 실행하고 파일 열기 대화 상자에서 파일 유형을 선택할 때 아래와 같이 PSD 파일에 대한 필터가 등록되어있으면 정상적으로 설치된 것입니다.

3단계: PSD 파일을 PDN 파일로 저장하기

변환하려고 하는 PSD 파일을 PDN 파일로 저장해야 합니다. 일단 PSD 파일을 Paint.net에서 열었을 때 원본 PSD 파일과 차이점이 없는지 한 번 확인은 해야 합니다. 디자이너나 아트워크에 관여하는 다른 사람과 내용을 검토해본 다음 내용에 이상이 없으면 PDN 파일로 저장하여 4단계로 진행합니다.

4단계: PDN2PNG 명령줄 유틸리티로 레이어 별로 투명 PNG로 저장하기

PSD 파일을 PDN 파일로 변환한 다음 실제로 하려는 일은 각각의 레이어를 투명 PNG로 나누어 저장하는 일이 되겠지요. 이 작업 역시 Paint.net에서 직접 수행하는 것은 현재 매우 손이 많이 가고 번거로운 작업이기 때문에 자동화를 위하여 반드시 도구가 필요한데 Paint.net 없이 이를 처리해주는 도구가 PDN2PNG 입니다. http://forums.comsquare.ch/viewforum.php?title=pdn2png 에서 다운로드할 수 있으며, 별도로 제품화된 소프트웨어가 아닌 관계로 사이트에 접속되지 않을 가능성을 염두에 두어 제 SkyDrive에 파일 사본을 올려두었습니다. (문제가 될 경우 삭제하겠습니다.)

PDN2PNG 및 PSD Load Plugin 다운로드: http://sdrv.ms/VQfZyE

이 프로그램을 명령줄 도구로 찾기 쉬운 위치에 파일을 압축 해제하여 복사하거나 PATH 환경 변수 등으로 검색할 수 있도록 설치합니다.

PDN 파일이 정상적으로 렌더링되었을 때의 전체 모습을 PNG 파일로 바꾸려면 다른 스위치 없이 아래와 같이 명령어를 지정하면 됩니다.

pdn2png "PDN 파일 경로"

PDN 파일 안에 들어있는 각각의 레이어들을 모두 낱개의 PNG 파일로 바꾸려면 아래와 같이 /split 스위치를 사용하여 명령어를 지정하면 현재 작업 중인 디렉터리 앞으로 낱개의 PNG 파일들이 레이어의 이름을 사용하여 만들어집니다.

pdn2png /split "PDN 파일 경로"

전체 레이어 대신 특정 레이어 인덱스를 PNG 파일로 바꾸려면 아래와 같이 스위치를 지정합니다.

pdn2png /index="인덱스 번호" "PDN 파일 경로"

5단계: 그림 자르기

pdn2png 명령의 /split 스위치를 사용하여 모든 PNG 파일들을 만들고 난 다음에 각 PNG 파일들을 살펴보면 분할은 되어있지만 여전히 프로그램에서 원하는 조각 그림의 형태에는 조금 거리가 있습니다. 디자인 아트워크 기준으로 정확히 제 자리에 아트워크가 변환되어있긴 하지만 불필요하게 여백이 많이 남는 것을 볼 수 있습니다. 이를 깔끔하게 제거할 수 있는 방법은 약간의 노동(?)을 요구합니다. 5단계의 작업을 위해서는 Paint.net 또는 다른 적절한 도구를 사용하면 되지만 여기서는 Paint.net으로 작업하는 요령을 소개하고자 합니다.

  • Paint.net으로 나누어진 PNG 파일을 엽니다.
  • Magic Wand 툴을 도구 모음에서 왼쪽 그림과 같이 선택합니다.
  • Magic Wand 툴의 경계선 감지 유연성을 아래 그림과 같이 0%로 설정합니다. 어차피 투명한 배경과 투명하지 않은 Object로 경계가 극명하게 구분된 상태의 이미지이기 때문에 정확히 이미지를 자를 것에만 신경쓰면 됩니다.
  • 이제 아래 그림과 같이 투명 배경을 Magic Wand로 선택합니다. 이렇게 선택하여 투명한 영역과 투명하지 않은 영역을 집합 관계로 봤을 때 차집합 관계로 설정할 수 있습니다.


  • 키보드 단축키 Ctrl+I 키를 눌러 영역을 반전시킵니다. 투명한 영역 선택에 대한 나머지 반전이므로 투명하지 않은 영역 모두를 선택하는 셈이 됩니다.


  • 이제 여기서 키보드 단축키 Ctrl+Shift+X키를 눌러 선택된 영역에 맞추어 캔버스의 크기를 아래 그림과 같이 줄입니다. 크기는 자동으로 산출되므로 이미지가 잘릴 걱정은 하지 않아도 됩니다.

    주의 사항: SnagIt의 경우 단축키로 Ctrl+Shift+X를 이미 전역적으로 바인딩하고 있기 때문에 이 동작이 Paint.net으로 전달되지 않고 무시될 수 있습니다. SnagIt 혹은 이 단축 키 조합에 의존하는 다른 프로그램이 있을 경우 작업하는 동안 잠시 프로그램을 종료해야 합니다.


  • 키보드의 Esc 키를 눌러 선택 영역을 해제하고 단축키 Ctrl+S 키를 눌러 아래 그림과 같이 최적의 이미지 옵션을 선택하여 저장합니다. 나머지 파일들도 같은 방법으로 계속 작업하면 됩니다.


이렇게 해서 디자이너가 개발자에게 가져다준 PSD 파일을 개발자가 원하는 PNG 파일로 성공적으로 변환할 수 있습니다. 디자이너와 개발자 모두 서로에게 도움이 될 수 있을 것입니다. 오늘 한 번 시험삼아 활용해보시는것은 어떨까요? :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2012. 9. 15. 20:37

안녕하세요. Windows Azure MVP 남정현입니다. 오늘은 Visual Studio 2012 출시와 더불어서 Express Edition의 업그레이드에 대한 이야기를 전해드리려고 합니다.

개인적으로 매우 좋아하고 아끼는 Visual Studio 제품 라인 업 중에 Express Edition이 있습니다. 무료로 제공되는 개발 도구임에도 기능에서나 활용 면에서 부족함이 전혀 없고, 제 스스로에게 있어서 작업 시간을 줄여주고 시행 착오를 최소화하는데에 지대한 공헌을 하는 멋진 개발 툴입니다.

이번 2012 라인 업에서는 아래와 같이 구성이 변경되었습니다.

  • Visual Studio 2012 Express for Web: 기존의 Visual Web Developer 2010을 이어서 업그레이드된 버전으로 ASP.NET 4.5와 Windows Azure 최신 개발 툴킷, Silverlight 개발 환경등을 포함하고 있습니다.
  • Visual Studio 2012 Express for Desktop: 기존의 Visual C# Express 2010, Visual Basic .NET Express 2010, Visual C++ Express 2010을 통합하여 데스크탑 응용프로그램 개발에 최적화된 버전으로 업그레이드되었습니다.
  • Visual Studio 2012 Express for Windows 8: Windows 8에서 새로 추가된 Windows Store 앱을 만들기 위하여 필요한 개발 도구로 동시에 Expression Blend for Windows 8이 같이 설치됩니다.
  • Visual Studio Team Foundation Server 2012 Express: 고가의 상용 버전 제품으로만 알려져있었던 Team Foundation Server도 Express 버전을 새로 출시하게 되었습니다. 소규모 개발 팀을 운영 중인 경우 한 번즈음 고려해볼 수 있는 형상 관리, 작업 관리, 빌드 자동화를 제공합니다.

언어 별로 나누어져 있었기 때문에 장점이자 단점으로 동시에 작용하던 작고 가벼움은 아쉽게도 더 이상 존재하지는 않습니다. 그렇지만 Express Edition 특유의 한계를 극복하고 더 강력한 기능을 더하고 단순히 학습용이 아닌 소규모 개발 팀을 위한 배려를 모두 포함하고 있다는 것은 매우 기쁜 일입니다.

그리고 실제로 Visual Studio 2012 전체 버전을 구입하시기 전에 제품의 표면적인 기능만을 제한된 시간 내에 평가해야 하는 트라이얼 버전 대신, 실제 업무에도 자연스럽게 반영해볼 수 있는 Express Edition을 통해서 충분한 시간을 가지면서 활용하시면 좀 더 좋은 부분을 많이 보실 수 있을 것이라고 기대합니다.

Web과 Desktop 버전은 Windows 운영 체제 버전과 관계없이 사용이 가능하며, Windows 8 버전의 경우에는 실제로 Windows 8 운영 체제 위에서 실행되어야만 개발 환경 구축이 가능합니다. 그리고 이전과 마찬가지로, 무료로 사용이 가능하고 상용으로도 활용이 가능하지만 설치 후 기간 내에 Microsoft 등록 페이지에 가서 제품에 대한 25자리 등록 번호를 받아서 등록해야 하는 절차는 변함 없습니다.

2012 Express Edition과 2010 Express Edition을 다운로드하시려면 http://www.microsoft.com/visualstudio/kor/downloads 페이지로 가시면 됩니다. :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

  1. 현재 네이버 메인에 나오고 있습니다.

    2013.01.28 15:38 신고 [ ADDR : EDIT/ DEL : REPLY ]

Windows + .NET2012. 7. 28. 00:25

[2014.03.18 Update] XpressEngine 1.5 버전에서 사용하는 구형 패스워드 해시 함수에 대한 내용을 업데이트하였습니다.

asp.net 기반의 프로젝트를 진행하면서 PHP나 MySQL 기반의 데이터베이스와 상호작용해야 하는 상황이 자주 있는데, MySQL의 password 함수를 사용하여 만든 Hash 기반의 Opaque Single Way 암호화 토큰을 비교해야 하는 때가 있습니다. SHA1을 사용하여 만드는 해시 결과 값이지만 명확한 결과와 구현 과정을 이해하기에는 쉽지 않아 같은 기능을 .NET으로 구현하는데에는 약간의 노력이 필요합니다. 정보 공유를 위해서, 그리고 개인적인 편의를 위해서 블로그 글로 간단히 팁을 올려봅니다.

출처: http://stackoverflow.com/questions/868482/simulating-mysqls-password-encryption-using-net-or-ms-sql

using System;
using System.Security.Cryptography;
using System.Text;

// 중략

public string CalculateHash(string key)
{
    byte[] keyArray = Encoding.UTF8.GetBytes(key);

    using (SHA1Managed enc = new SHA1Managed())
    {
        byte[] encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray));
        StringBuilder myBuilder = new StringBuilder(encodedKey.Length);

        for (int i = 0; i < encodedKey.Length; i++)
            myBuilder.Append(encodedKey[i].ToString("X2"));

        return String.Concat("*", myBuilder.ToString());
    }
}

MySQL의 새 password API는 간단히 요약하면 .NET의 SHA1Managed와 거의 동일하며, 앞에 Asterisk를 붙이는 Behavior는 독자적인 것입니다. 이 기능을 사용하여 XpressEngine이나 다른 MySQL 기반 응용프로그램과 안전하게 크레덴셜을 공유하고 Single Membership 체제를 유지할 수 있습니다.

[2014.03.18 Update]

만약 구 버전의 XE 1.5의 Password Hash 함수를 필요로 하는 경우 다음의 코드를 대신 사용합니다.

public static string CalculateHash(string key)

        {

            byte[] keyArray = Encoding.UTF8.GetBytes(key);


            using (HashAlgorithm enc = new MD5Cng())

            {

                byte[] encodedKey = enc.ComputeHash(keyArray);

                StringBuilder myBuilder = new StringBuilder(encodedKey.Length);


                for (int i = 0; i < encodedKey.Length; i++)

                    myBuilder.Append(encodedKey[i].ToString("x2"));


                return String.Concat(myBuilder.ToString());

            }

        }

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2012. 7. 13. 18:07

안녕하세요. Windows Azure MVP 남정현입니다.

이전에 신청한적이 있었던 Windows Azure Media Service Preview 프로그램에 대한 테스트 계정을 오늘 얻을 수 있었습니다. 이에 맞추어 간단한 기능을 테스트해보고 처음으로 블로그 포스트를 남겨봅니다. Windows Azure Media Service는 Windows Azure Platform에 근래에 새로 추가된 클라우스 서비스의 한 종류로, 여러분이 가지고 있는 동영상 컨텐츠를 클라우드 컴퓨팅 상의 자원을 활용하여 인코딩하고 그 내용을 곧바로 저장소와 CDN에 게시할 수 있도록 도와주는 서비스입니다. 현재는 프리뷰 버전으로 나온 상태이므로 기능이나 API에 많은 변동이 있을 수 있습니다. 그러나 서비스의 기본 방향이나 목적은 지금 설명 드린 내용이 주된 내용이 되므로 국내외에서 미디어 관련 서비스를 활용하고자 하는 많은 고객들의 관심을 얻을 수 있을 것으로 봅니다.

Windows Azure Media Service를 신청하려면?

Windows Azure Media Service는 현재 신청을 별도로 받아서 계정을 할당하는 방식으로 사용해 볼 수 있습니다. 이를 위해서는 우선 Windows Azure 계정을 하나 만드셔야 하며, http://www.windowsazure.com/ 에서 신청하실 수 있습니다. 국내에 서비스가 정식으로 시작되었기 때문에, 이제는 해외 거주지 정보가 필요하지 않고 쉽게 신청을 마무리하실 수 있습니다.

Windows Azure 계정 관리 홈페이지 (account.windowsazure.com)에 접속하신 후에, "미리 보기 기능"을 클릭하면 현재 신청 가능한 프리뷰 프로그램들이 열거됩니다. 이 중에서 Media Services 항목을 신청하시면 대기열에 예약이 됩니다. 승인이 완료되면 아래 그림과 같이 관리 홈페이지 (manage.windowsazure.com)에 접속하였을 때 Media Service에 대한 메뉴가 새로 나타납니다.

 

미디어 서비스를 만든 후에는 새로운 미디어 서비스를 신청해야 하며, 이 때 미디어 서비스와 연결할 스토리지 계정을 하나 지정하게 됩니다. 미디어 서비스 API로 동영상을 업로드하고 인코딩 후 결과물을 받아보는 것이 모두 연결된 스토리지 계정을 통해 이루어지고, 미디어 서비스 자체는 현재 프리뷰 프로그램 상태에 있기 때문에 미디어 서비스를 통해서 실행되는 비용은 발생하지 않지만 스토리지에 파일을 보관하고 트랜잭션이 발생하는 것에 대해서는 비용이 따로 계산이 됩니다.

.NET Framework 기반 미디어 서비스 API 개발 환경 구성하기

.NET Framework로 미디어 서비스 API를 호출하기 위해서는 제공되는 SDK를 사용하는 방법이 가장 유용하고 편리합니다. 이를 위해서는 몇 가지 소프트웨어 패키지를 설치해야 하며, 다음의 패키지를 다운로드하여 설치하시면 됩니다.

미디어 서비스 API 자체가 REST API이므로 .NET 이외의 언어에서도 얼마든지 호출이 가능합니다. 기타 언어에 대한 SDK 및 지원 내용, 구성 방법은 아래의 각 링크를 참고하시면 됩니다.

테스트 프로젝트 구성하기

이 예제에서는 Windows 데스크톱 응용프로그램 환경에서 코드를 작성하는 것을 기준으로 예를 들어보겠습니다. Visual Web Developer 2010 SP1이나 Visual Studio 2012 for Web RC를 설치한 경우, Windows 클래스 라이브러리 프로젝트를 만들고 프로젝트 속성에서 프로젝트의 출력 유형을 클래스 라이브러리에서 콘솔이나 Windows로 변경하면 직접 실행 가능한 EXE 파일로 빌드 결과물을 만들 수 있습니다.

콘솔 프로그램을 하나 만들고, 프로젝트 참조에 필요한 라이브러리들을 모두 추가해야합니다.

우선 WCF Data Service 5.0 for OData v3 어셈블리들을 추가해야 합니다. 64비트 컴퓨터를 사용 중인 경우 %programfiles(x86)%\Microsoft WCF Data Services\5.0\bin\.NETFramework 폴더를, 32비트 컴퓨터를 사용 중인 경우 %programfiles%\Microsoft WCF Data Services\5.0\bin\.NETFramework 폴더에 있는 아래의 5개 DLL을 참조로 추가합니다.

  • Microsoft.Data.Edm.dll
  • Microsoft.Data.OData.dll
  • Microsoft.Data.Services.Client.dll
  • Microsoft.Data.Services.dll
  • System.Spatial.dll

이어서 Windows Azure Storage Client 어셈블리를 추가해야 합니다. %programfiles%\Microsoft SDKs\Windows Azure\.NET SDK\2012-06\bin 폴더로 이동하여 아래의 DLL을 참조로 추가합니다.

  • Microsoft.WindowsAzure.StorageClient.dll

이어서 Windows Azure Media Service SDK 어셈블리를 추가해야 합니다. 64비트 컴퓨터를 사용 중인 경우 %programfiles(x86)%\Microsoft SDKs\Windows Azure Media Services\Services\v1.0 폴더를, 32비트 컴퓨터를 사용 중인 경우 %programfiles%\Microsoft SDKs\Windows Azure Media Services\Services\v1.0 폴더에 있는 아래의 DLL을 참조로 추가합니다.

  • Microsoft.WindowsAzure.MediaServices.Client.dll

마지막으로, Windows Azure Media Service SDK가 필요로 하는 Azure Storage Client DLL의 어셈블리 버전에 대하여 바인딩 리디렉션을 지정하여 Azure Media Service SDK가 최신 버전의 Windows Azure Storage Client 라이브러리와 상호작용할 수 있도록 조정해야 합니다. 이를 위하여 프로젝트에 app.config 파일 (웹의 경우 web.config 파일)을 추가하여 아래의 섹션을 추가합니다.

<?xml version="1.0"?>
<configuration>
...
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.WindowsAzure.StorageClient"
          publicKeyToken="31bf3856ad364e35"
          culture="neutral" />
        <bindingRedirect oldVersion="1.1.0.0" newVersion="1.7.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
...
</configuration>

설치한 Azure SDK의 버전이 1.6 버전인 경우 위의 예제 코드에서 1.7.0.0 대신 1.6.0.0으로 지정하면 됩니다. 저의 경우, Windows 8용 Azure SDK를 설치했기 때문에 1.7 버전으로 지정하였습니다.

테스트 프로젝트 코딩하기

아래의 프로그램 코드를 잠시 살펴보겠습니다.

using System;
using System.Linq;
using Microsoft.WindowsAzure.MediaServices.Client;

namespace MediaServiceTestDrive
{
    class Program
    {
        static void Main(string[] args)
        {
            CloudMediaContext mediaContext = new CloudMediaContext(
                "" /* Account Name */,
                "" /* Account Key */
                );

            IAsset asset = mediaContext.Assets.Create(
                "" /* File Path */,
                AssetCreationOptions.CommonEncryptionProtected);

            IJob job = mediaContext.Jobs.Create("Sample Job");

            IMediaProcessor mediaProcessor = mediaContext
                .MediaProcessors.Where(x => x.Name == "Windows Azure Media Encoder")
                .FirstOrDefault();

            ITask task = job.Tasks.AddNew(
                "Sample task", mediaProcessor,
                "H.264 256k DSL CBR" /* Encoding Template Name */,
                TaskCreationOptions.None);

            task.InputMediaAssets.Add(asset);
            task.OutputMediaAssets.AddNew(
                "Output asset",
                true, AssetCreationOptions.None);

            job.Submit();

            while (true)
            {
                foreach (var eachJob in mediaContext.Jobs.ToList())
                {
                    Console.WriteLine(eachJob.State);
                }
                System.Threading.Thread.Sleep(5000);
            }
        }
    }
}

호출 절차가 다소 복잡해 보이지만 논리적으로 여러 작업들을 비동기 방식으로 찾아볼 수 있도록 구성한 것이 특징입니다. 우선 제일 먼저 CloudMediaServiceContext 클래스의 인스턴스를 만들어 연결을 성립시킵니다. 이 과정에서 계정 이름과 비밀 키 값을 요구하는 데 이 부분은 manage.windowsazure.com에 나와있는 미디어 서비스의 계정 이름과 키 값을 지정하면 됩니다. 스토리지 서비스에 대한 계정 이름과 키 값이 아님을 유의합니다. 스토리지 서비스에 대한 계정 이름과 키 값은 미디어 서비스 내부에서 별도로 동기화하여 보관하는 기능이 있으므로 이를 참고합니다.

그 다음 파일을 스토리지에 올리기 위한 절차이자 인코딩 대상을 지정하기 위한 절차로 Asset을 만듭니다. Asset을 만들 때 지정하는 인수에는 로컬 컴퓨터의 미디어 파일의 경로를 지정하며, 이것을 스토리지에 업로드하기 위하여 시간이 다소 걸릴 수 있습니다.

그 다음으로 작업을 하나 정의합니다. 작업 안에는 여러 가지의 세부 태스크가 존재할 수 있으며 이것을 논리적으로 하나의 작업으로 취급합니다.

그 다음에는 수행하려는 작업을 처리해줄 수 있는 미디어 프로세서 개체를 가져와야 합니다. 프로세서는 Azure Media Service가 제공하는 범위 안에서만 사용이 가능함에 유의합니다. LINQ 식을 사용하여 미디어 프로세서 개체를 확인하고 그 중 필요한 것을 택합니다. 여기서는 단순 인코딩 처리를 위하여 Windows Azure Media Encoder를 선택합니다.

그 다음으로 작업에 태스크를 하나 추가합니다. 태스크를 추가할 때에는 태스크의 이름과 미디어 프로세서 개체, 미디어 프로세서의 동작 특성을 정의하는 인코딩 템플릿 이름 등을 지정합니다. Windows Azure Media Encoder의 경우 인코딩 템플릿 이름에 대한 정보를 Expression Encoder SDK에서 확인할 수 있습니다. 이름들에 대한 목록은 http://msdn.microsoft.com/en-us/library/microsoft.expression.encoder.presets_members.aspx 에서 확인 가능합니다.

만들어진 태스크의 입력과 출력 대상을 정의하는데, 앞서 지정한 asset을 입력에 추가하고, 출력에는 새로운 asset을 생성하도록 예약합니다.

모든 구성이 끝나면 Job 객체의 Submit() 메서드를 호출하여 작업을 의뢰합니다. 이 떄 부터 모니터링 기능을 사용하여 작업의 진행 상황을 실시간으로 질의할 수 있습니다. 각각의 작업이 완료되면 State 속성이 Completed로 나타나므로 이를 통해서 작업 완료 여부를 확인 가능합니다.

실제로 어떻게 결과물이 나타나는가?

스토리지를 실제로 접속해 보면 새로운 컨테이너들이 만들어집니다. 입력용 Asset을 위한 전용 컨테이너가 먼저 만들어지고, 출력용 Asset을 위한 전용 컨테이너가 나중에 만들어지는 순서입니다. 각각의 컨테이너들은 초기에는 비공개 상태로 설정되어있습니다.

입력용 컨테이너로 만들어진 것을 열어보면 요청한 파일어 업로드된 것을 볼 수 있습니다.

출력용 컨테이너에는 기대한대로 인코딩된 파일과 메타 데이터 파일이 들어있습니다. 

출력용 컨테이너 폴더의 퍼미션 설정을 BLOB 공개로 전환하고 CDN을 연결하면 즉시 서비스 가능한 동영상이 제공되는 것입니다.

좀 더 자세한 정보를 보려면?

간단하게 한 페이지 안에 기본적인 코딩 레시피를 모아놓은 페이지가 있으므로 이 이후에 좀 더 구체적인 작업을 하기 원한다면 아래 페이지에서 내용을 확인하기 바랍니다. PlayReady와 같은 DRM 적용도 매우 쉽게 수행할 수 있습니다.

http://go.microsoft.com/fwlink/?LinkId=251359&clcid=0x412

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2012. 2. 10. 01:30

지난 아티클에서는 Phalanger와 PHP 사이에 차이점들이 있다고 말씀드렸습니다. 구체적으로 어떤 차이점들이 있을까요? 여러 프로그래밍 언어를 지원한다는 사실이 가장 큰 차이점이고 닷넷 기반 위에서 실행된다는 것이 구분되는 점이겠지만 이런 점을 차치하고 PHP 관점에서 차이점을 살펴본다면 지금 이야기하려는 토픽들에 대한 이야기가 빠질 수 없을 것입니다.

App_Code 폴더의 사용

Phalanger가 ASP.NET을 기반으로 하고 있기 때문에 자동으로 이어받는 특성으로, App_Code 폴더의 사용에 관한 부분이 있습니다. ASP.NET에서는 App_Code 폴더 안에 낱개 코드 파일들을 넣어두면 이것을 자동으로 웹 페이지의 서버 런타임에서 자유롭게 가져다쓸 수 있다고 하였는데, Phalanger도 마찬가지입니다. 웹 페이지를 렌더링하기 위한 목적이 아닌 공통이 되는 PHP 코드를 이 폴더에 넣어두기만 하면 자동으로 이 폴더에 속한 모든 PHP 코드들이 글로벌 문맥 상에서 사용 가능하게 활성화됩니다.

단, 조심해야 할 부작용이 하나 있다면 여기에 지나치게 많은 코드를 배치할 경우 컴파일 시간이 늘어나서 처음 사이트를 시작할 때 시간이 오래 걸리게 될 가능성이 있습니다. 안타깝게도 C나 C++처럼 병렬 컴파일은 아직 지원되지 않기 때문에 컴파일 시간이 오래 걸릴 경우 다양한 문제를 야기할 가능성이 있습니다.

php.ini와 같은 Global Configuration이 아닌 web.config에 의한 설정

PHP의 경우 설정을 변경하기 위해서는 PHP 전체의 설정을 주관하는 php.ini 파일을 업데이트하거나, PHP를 다시 컴파일하여 설치하는 번거로운 과정을 거쳐야만 모듈에 대한 설정이나 추가/제거가 가능했습니다. 하지만 Phalanger의 경우 현재 만들어진 응용프로그램 풀마다 다른 설정을 가지도록 구성할 수 있으므로 좀 더 자유도 높은 설정이 가능합니다. 이를 위해서 web.config 파일을 수정하고 저장하기만 하면 됩니다.

이러한 설정을 다루기 위해서는 phpNet이라는 XML 요소를 web.config에 지정해야 하는데, 그냥 지정할 수는 없고 반드시 적절한 처리기를 연결해주어야 합니다. web.config은 단순한 XML 파일이 아니라 닷넷 프레임워크가 직접 내용을 검사하고 분석하는 프로그램 코드의 일부이기 때문에 규칙을 준수하는 것이 매우 중요합니다.

phpNet 요소를 추가하려면 web.config에서 <configuration> 요소의 제일 첫 번째 노드로 아래 XML 조각이 배치되어야 합니다.

<configSections>
<section name="phpNet" type="PHP.Core.ConfigurationSectionHandler, PhpNetCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=0a8e8c4c76728c71" />
</configSections>

그 다음, 보기에 편리한 위치에 phpNet 요소를 추가합니다. 보통 아래의 코드 조각으로 최초 설정을 시작하면 무난합니다.

<phpNet>
<classLibrary>
  <add assembly="PhpNetClassLibrary, Version=3.0.0.0, Culture=neutral, PublicKeyToken=4af37afe3cde05fb" section="bcl" />
  <add assembly="PhpNetXmlDom, Version=3.0.0.0, Culture=neutral, PublicKeyToken=2771987119c16a03" section="dom"/>
</classLibrary>   
</phpNet>

php.ini 파일의 샘플 사본을 복사하여 php.ini 파일로 사용하던 것과 비슷한 접근 방법이지만 각 사이트 혹은 도메인 별로 따로 사용하는 web.config 파일 안에서 이러한 설정을 다루는 것이 중요한 차이점입니다. 그리고 무엇보다도 안심해도 좋은 것은 INI 파일처럼 프로그램이 잘못 다루게 될 가능성이 있는 파일이 아니라, XML의 형태로 설정 파일이 관리되므로 web.config 파일을 건드리는 다른 써드 파티 어플리케이션 때문에 Phalanger의 설정이 깨지거나 변형될 일이 거의 없다는 점입니다.

위의 기본 설정을 지정하면 Phalanger에서 기본적인 PHP API를 사용할 수 있으며, PHP5부터 기본으로 제공되는 SimpleXMLElement도 위의 설정으로 기본으로 활성화됩니다.

PHP/CLR의 사용

이제 위의 설정을 토대로 PHP/CLR을 활성화하여 닷넷 프레임워크의 기본 API를 Phalanger에서 즉시 호출하여 사용할 수 있습니다. 위의 <phpNet> 요소 아래에 다음의 XML 요소를 추가하면 됩니다.

<compiler>
  <set name="LanguageFeatures">
    <add value="PhpClr" />
  </set>
</compiler>

그리고 <classLibrary> 요소 아래에 .NET Framework 기본 어셈블리에 대한 레퍼런스를 추가합니다.

<classLibrary>
  <add assembly="mscorlib" />
  <add assembly="System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  <add assembly="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  <add assembly="PhpNetClassLibrary, Version=3.0.0.0, Culture=neutral, PublicKeyToken=4af37afe3cde05fb" section="bcl" />
  <add assembly="PhpNetXmlDom, Version=3.0.0.0, Culture=neutral, PublicKeyToken=2771987119c16a03" section="dom"/>
</classLibrary>

이제 새로 추가한 코드가 의도한대로 잘 작동하는지 살펴보기 위하여, 이미지 리사이징을 수행하는 샘플 코드를 Phalanger 위에서 실행하도록 PHP/CLR 기반으로 코드를 만들어보도록 하겠습니다. 이 코드는 http://wiki.php-compiler.net/Code_Samples/Resize_image 의 예제를 발췌하여 조금 변형한 것입니다.

<?php
use System\Drawing\Bitmap;
use System\Drawing\Graphics;
use System\Drawing\GraphicsUnit;
use System\Drawing\Rectangle;
use System\Web\HttpContext;

function resize_imageSysDraw($from,$wid,$hgt)
{
  $bmp = Bitmap::FromFile($from);
  $fmt = $bmp->RawFormat;
  $new = new Bitmap($wid, $hgt);
  $gr = Graphics::FromImage($new);
  $gr->DrawImage($bmp,
    new Rectangle(0,0,$wid,$hgt),
    new Rectangle(0,0,$bmp->Width, $bmp->Height),
    GraphicsUnit::Pixel);
  $gr->Dispose();
  $new->Save(HttpContext::$Current->Response->OutputStream, $fmt);
  $new->Dispose();
}

resize_imageSysDraw(realpath('Penguins.jpg'), 320, 240);
?>

PHP/CLR의 경우 여느 닷넷 언어들과 마찬가지로 네임스페이스에 속한 클래스에 대한 참조를 use 명령어로 지정하고 있으며, 정적 멤버에 대해서는 :: 연산자를, 객체 생성은 new 연산자를 사용하였습니다. resize_imageSysDraw 함수에서는 ASP.NET의 HttpContext를 가져와서 기본 출력 대신 비트맵 이미지를 내보내도록 만들었고 그 결과 아래와 같이 축소된 이미지가 렌더링되서 나타나게 됩니다.

Phalanger의 LINQ 지원

이제 마지막으로 PHP/CLR의 하이라이트라고 할 수 있는 LINQ 지원에 대해서 살펴보겠습니다. LINQ는 Microsoft Research에서 C# 언어의 확장 사양인 C-omega 언어의 일부로 개발 중이던 사양을 정규화하여 Production Spec으로 만든 것으로, C# 이외에 VB.NET에도 영향을 주었으며 Prism이나 지금 소개하는 Phalanger에서도 개념을 적극 채택하여 정규 사양으로 활용 중입니다. 그리고 F#은 이러한 접근을 더욱 드라마틱하게 활용하여 함수형 언어로 발전시키기도 하였습니다.

LINQ에 대해서 이야기하려면 책을 한 권 따로 만들어야할 만큼 방대합니다. 그래서 자세한 이야기는 하지 않고, LINQ 자체에 대해서 진지하게 학습하기 원한다면 LINQ 관련 국내외 도서들을 검토하기 바랍니다. 개인적으로는 "생각하는 C# LINQ"라는 책을 추천합니다. :-)

http://kangcom.com/sub/view.asp?sku=200809180001&mcd=571

LINQ는 한 마디로 이야기하면, 프로그래밍 코드를 한 방향에서만 바라보도록 뷰 포인트의 시각을 고정한 것과 같습니다. 본디, 어떤 연관성이 있는 데이터 집합을 접근하는 방법에는 여러 가지 방법이 있을 수 있지만 LINQ는 데이터가 어떤 순서로 들어있든, 어떤 형태로 연결되어있든 관계없이 데이터를 꺼내올 수 있도록 도와주는 Iterator 패턴의 한 형태인 Enumerator를 조금 독특하게 해석하였습니다.

Enumerator가 열거할 대상을 미리 정할 수 있도록 만들고, 열거할 때 조건을 지정하여 필요없는 데이터는 건너뛸 수 있게 해준다던지 이런 취지에서 해석을 한 것이 LINQ입니다. 그리고 Enumerator를 수정하게 되는 시점이 이미 메모리 상에 저장된 데이터 셋에 대한 작업인지, 아니면 아직 수신되지 않은 미지의 데이터 셋에 대한 작업인지에 따라서도 지연 실행이냐 즉시 실행이냐 이렇게 구분하기도 하구요. 그러면서도 항상 잃지 않는 것은 핵심은 Enumerator라는 사실이며, 이에 입각하여 배열이나 리스트같은 정규화된 자료 구조로 변환할 수 있는 길을 항상 열어놓아 최대한의 유연성을 부여하기도 합니다.

어렵게 들릴 수도 있지만 Enumerator를 수정할 수 있게 해준다는 컨셉은 생각보다 활용 폭이 넓은데, 가장 가까이 있는 예로는 SQL 쿼리가 될 수 있습니다. 처음의 아이디어는 SQL 쿼리를 이용하여 전체 데이터 셋보다 가능한 적게 데이터를 반환하여 네트워크 트래픽을 줄이고 빠르게 데이터를 검색할 수 있도록 최적화하자는 것에 있었을 것이며, 이것을 좀 더 프로그래밍 언어와 친화적으로 만들 방법을 모색한 끝에 LINQ to SQL이 나타나게 된 셈입니다. 그리고 이를 필두로 접근할 수 있는 모든 유형의 컬렉션에 대해서 이런 아이디어를 대입하여 현재는 오픈 소스를 찾아보면 정말 엄청나게 많은 LINQ provider들을 발견할 수 있을 정도입니다.

이렇게 독창적이고 전례없던 기술을 Phalanger에서도 이용할 수 있다는 것은 매우 좋은 일입니다. <phpNet> 요소에 대해 PHP-CLR을 활성화하도록 설정을 수정한 후 아래 코드를 테스트해보기 바랍니다.

<?php
$myarray = json_decode('[
    {"label":"foo","name":"baz"},
    {"label":"boop","name":"beep2"},
    {"label":"foo","name":"baz1"},
    {"label":"boop","name":"beep3"},
    {"label":"foo","name":"baz2"},
    {"label":"boop","name":"beep1"}
]', true);

$result =
from $myarray as $x
where $x['label'] == 'foo'
select $x['name'];

foreach ($result as $x) {
    print($x.'<br />');
}

print_r($result);

?>

json_decode라는 기본 PHP 함수를 이용하여 JSON을 PHP 연관 배열로 바꾸고, 이것을 LINQ로 조회한 다음, 그 결과를 foreach 문을 통해서 출력하도록 만들었습니다. C#이나 VB.NET의 LINQ와 약간 다른 점은, from 절에서 in 연산자 대신 as 연산자를 사용하고 in 연산자와는 도치되는 좌/우항 관계를 가집니다. 즉, [나열 변수] in [데이터 소스] 에서 [데이터 소스] as [나열 변수]로 바뀝니다. 그리고 이것은 foreach 문에도 동일하게 적용됩니다. 아래는 실행 결과입니다.

PHP, JSON, 그리고 LINQ가 한 자리에 모여 매우 재미있는 상호 작용을 이룬 것을 볼 수 있습니다. 이 정도면 닷넷에서의 웹 프로그래밍이 이전과는 제법 많이 달라질 수 있다는 것을 체감할 수 있을 것입니다.

다음번에는 Phalanger가 기존 PHP의 모듈들을 어떻게 다루고 관리하는지에 대한 상세한 내용을 살펴보도록 하겠습니다. 긴 글 읽어주셔서 감사합니다. :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2012. 2. 8. 02:00

지난 아티클에 이어 오늘은 Phalanger를 이용하여 C#과 VB.NET 코드를 동시에 활용하는 예를 한 번 조명해보려고 합니다. 사실 이것이 Phalanger의 하이라이트라고 하여도 무방하지 않습니다. 기존의 C#과 VB.NET 로직을 재사용하면서도 Phalanger로 빠르고 가볍게 웹 페이지를 풀어나가는 방식은 여러모로 웹 개발에 가속을 붙여줄 것입니다.

계속 설명하기 전에, Phalanger가 ASP.NET 위에서 실행되기 때문에 적용되는 한 가지 특수한 규칙을 이야기할 것이 있습니다. 바로 미리 정해진 이름의 폴더인데, Bin, App_Code 폴더입니다. 그 외 많은 폴더들이 있지만 지금은 두 가지만 살펴보겠습니다.

앞에서 이야기한대로 ASP.NET은 닷넷 프레임워크를 기반으로 작동한다고 하였고, 닷넷 프레임워크는 언어의 종류와 무관하게 MSIL이라는 코드로 컴파일되서 나오는 DLL 파일들을 취급할 수 있습니다. 그렇게 만들어지는 DLL 파일들은 Bin 폴더에 파일을 넣어주면면 자동으로 참조가 활성화되서 해당 웹 사이트 안의 모든 닷넷 코드에서 클래스 라이브러리를 사용할 수 있게 됩니다. 단, 주의할 것은 이 폴더 안에 아무 DLL이나 넣을 수 있는 것은 아니며 반드시 닷넷으로 컴파일된 DLL만 포함시킬 수 있습니다.

그리고 이번 아티클에서 가장 핵심이 되는 기능을 제공하는 폴더인 App_Code 폴더는, 컴파일을 하려는 모듈에 대한 코드를 여기에 넣어서 모든 페이지에서 공유할 수 있습니다. 기본적으로 이 폴더에는 한 종류의 언어에 해당되는 파일들만 넣을 수 있고, 그외 다른 언어의 파일이 포함되면 아래 이미지와 같은 오류가 발생합니다. 하지만 제가 이전에 소개했던 약간의 추가 설정을 적용하면 App_Code 폴더에서 여러 프로그래밍 언어를 동시에 사용할 수 있습니다.

위와 같이 나타나는 문제를 해결하기 위하여, App_Code 폴더 자체에서 사용할 언어는 Phalanger로 정하고, App_Code 폴더 안의 두 번째 수준의 디렉터리들에 C#이나 VB.NET 같은 언어를 사용하기로 결정합니다. 그리고 web.config 파일에 다음과 같이 <system.web> 요소 아래에 하위 디렉터리가 존재한다는 것을 알려줍니다.

<system.web>
<globalization requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="utf-8" />
<compilation>
  <codeSubDirectories>
    <add directoryName="Cs" />
    <add directoryName="Vb" />
  </codeSubDirectories>
</compilation>
</system.web>

그리고 App_Code 폴더에 각각 Cs 폴더와 Vb 폴더를 만듭니다. 폴더 이름에서 바로 알 수 있듯이 각각 C#과 VB.NET 코드를 따로 보관할 수 있도록 하고, 위의 그림처럼 오류가 발생하지 않으면서 자동으로 C#과 VB.NET으로 만든 코드를 Phalanger에서 액세스할 수 있도록 하게 할 것입니다. 이것으로 준비는 모두 끝났으며 우리가 원하는대로 C#과 VB.NET 코드를 추가하기만 하면됩니다.

C# 코드

using System;
using System.Collections.Generic;
using System.Web;

/// <summary>
/// Summary description for ClassName
/// </summary>
public class ClassName
{
    public string Name { get; set; }
    public int Age { get; set; }
    public override string ToString() {
        return String.Format("Name: {0} / Age: {1:D3}", Name, Age);
    }
}

VB.NET 코드

Imports Microsoft.VisualBasic

Public Class ClassName2
    Public Content As String
End Class

그리고 중요한 부분이 있습니다. Phalanger가 서브 디렉터리에 있는 코드들을 컴파일하였을 때 각각 따로 만들게 될 코드 조각들을 인식할 수 있도록 최소한 1개 이상의 임의의 PHP 파일이 필요합니다. 이후 아티클에서 따로 설명하겠지만 Phalanger는 App_Code 폴더 안에 있는 PHP 파일을 모두 자동으로 include하는 동작을 가지고 있습니다. (이것이 이전의 Original PHP와는 다른 부분입니다.)

지극히 일상적이고도 당연한 클래스 선언을 담고 있는 파일을 각 디렉터리에 추가하였습니다. 이제 웹 매트릭스의 폴더 레이아웃은 아래 그림과 같은 형태가 되면 됩니다.

이제 마지막으로 index.php 코드를 아래와 같이 작성합니다. 아래와 같이 작성하면 정말 PHP에서 C#과 VB.NET 코드를 자동으로 불러올 수 있을까요? 기대됩니다. :-)

<?php       
// C#
$test1 = new ClassName();
$test1->Name = "남정현";
$test1->Age = 2012-1987;
print $test1->ToString().'<br />';
print get_class($test1).'<br />';

// VB.NET
$test2 = new ClassName2();
$test2->Content = '<strong>안녕하세요!!!</strong>'.'<br />';
print $test2->Content;
print get_class($test2).'<br />';

phpinfo();
?>

ClassName은 C#으로, ClassName2는 VB.NET으로 만든 코드입니다. PHP/CLR 확장의 도움으로 Name, Age, Content 프로퍼티에 문자열을 대입하고 있으며, print 문을 이용하여 웹 페이지 상에 문자열을 출력합니다. 그리고 get_class라는 기본 PHP 함수를 사용하여 클래스 형식명을 가져오는 일도 하려고 하는군요. 마지막으로는 phpinfo() 함수를 호출하여 Phalanger 및 서버 시스템에 대한 정보도 덤프로 출력합니다. 이제 이 페이지를 실행해보면 아래와 같이 나타나게 될 것입니다. :-)

훌륭합니다! C#과 VB.NET 컴파일러를 따로 부르는 일 없이 앉은 자리에서 한 번에 코드를 컴파일하고, 이것을 PHP에서 보기 좋게 가져다 쓰는 일까지 해냈습니다.

다음 아티클에서는 마지막으로 Phalanger만의 고유한 기능이라고 할 수 있는 자동 include에 대해서 마지막으로 이야기해볼까 합니다. Original PHP에서는 include나 include_once 같은 함수를 어떤 인과 관계에 따라서 포함하게 될 것인지, 그리고 순서에 대해서도 많은 고민을 해야 했지만 Phalanger는 이러한 부분에 대한 고민을 많이 덜어낼 수 있습니다. 그리고 그 중심에는 App_Code 폴더의 역할이 크다고 했는데요, 이 부분에 대해서 집중적으로 살펴보려고 합니다.

 

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2011. 12. 26. 02:11

오늘 소개하려는 Visual Studio 확장 기능은 멀티 타기팅 팩의 기능을 매우 적극적으로 활용하는 똑똑한 확장 기능이다. 실무에서 3.5세대 혹은 4세대 닷넷 프레임워크를 적극적으로 사용 중인 개발자들이 국내에도 많이 있을텐데 이 경우 숟한 고민에 부딪히게 되는 것 중에 하나는 다중 플랫폼을 지원해야 한다는 점이다. 대충 열거해봐도 세 가지 이상은 된다. ASP.NET, Windows Presentation Foundation, Silverlight, 경우에 따라서는 XNA Game Studio나 Windows Phone 7.1까지 생각해야 하는 셈이다.

물론 신경써서 세심하게 잘 프로그래밍할 수 있을만큼 노련하다면야 이런 도구가 굳이 필요하지는 않겠지만 사람이 하는 일인지라 신경쓸 것이 많아지면 자연스레 귀찮을 수 밖에 없고 실수도 어디선가는 꼭 나온다. 이런 불분명하고 애매한 상황을 도구를 통하여 정확하게 잡아낼 수 있다면 괜찮지 않을까? Microsoft 개발 팀이 이런 문제를 해결해 줄 명쾌한 답을 Visual Studio Gallery에 올려놓았으니 참고하기 바란다. 아래의 URL에서 다운로드할 수 있다.

http://visualstudiogallery.msdn.microsoft.com/b0e0b5e9-e138-410b-ad10-00cb3caf4981/

Portable Library Tools를 설치하면 Visual Studio에 새로운 프로젝트 템플릿이 C#과 Visual Basic .NET에 대하여 Windows 카테고리 아래에 아래 그림과 같이 나타날 것이다.


시험삼아 새 프로젝트를 한 번 만들어보자. 이름에서 알 수 있듯이 특별할 것이 없는 공통되는 코드를 묶기 위한 클래스 라이브러리 프로젝트로서 만들어지며 일상적으로 여러분의 코드를 추가할 수 있다. 그런데 정말 중요한 것은 프로젝트 속성 안에 들어있다. 프로젝트 속성을 열어보면 아래와 같이 재미있는 구성을 볼 수 있다.

목표로 하는 프레임워크를 이전처럼 하나만 선택하는 것이 아니라 하나 이상을 동시에 지정할 수 있다. 이는 다시 말해서 이들 프레임워크의 공통 분모만을 사용하여 클래스 라이브러리를 정확히 프로그래밍할 수 있도록 보증한다는 의미이다. 그리고 Change 버튼을 클릭하면 더 유용한 쓰임새를 찾을 수 있다.

Visual Studio와 함께 설치된 다른 멀티 타기팅 팩이 있을 경우 여기에 모두 열거되어 여러분이 선택할 수 있도록 할 수 있다. 프로젝트의 종류가 많고 정말 일반적이면서도 널리 쓰여야 할 클래스 라이브러리를 만들어야 한다면 여기서 선택을 어떻게 하는가에 따라서 사용할 수 있는 API가 자동으로 필터링된다. 만약 위에서 선택한 플랫폼에서 사용할 수 없는 API에 대한 내용이 발견되면 곧바로 빌드 오류로 나타나기 때문에 문제를 쉽게 찾아낼 수 있다. 그리고 여기서 선택한 대로 해당 프로젝트에서 레퍼런스로 추가할 수 있으므로 생산성도 높일 수 있다. 즉, 솔루션이나 프로젝트를 여러벌로 나눠 관리할 필요 없이 한 곳에서 모두 관리할 수 있다.

이 도구를 사용하기 위해서는 Visual Studio 2010 전체 버전이 필요하며 SP1이 설치되어있어야 한다. 그리고 다른 타기팅 팩이 필요하다면 아래 URL에서 추가적으로 설치할 수 있다. 타기팅 팩은 그 자체로 설치할 수 있는 것은 아니고 보통은 해당 플랫폼에 대한 SDK 안에 같이 수록된다는 점에 유의해야 한다.

http://go.microsoft.com/fwlink/?LinkID=153626

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

  1. 이런거 있으면 클래스 만들때 호환성걱정은 많이 덜수 있겠네요

    2011.12.31 14:01 신고 [ ADDR : EDIT/ DEL : REPLY ]

Visual Studio2011. 4. 14. 17:00

안녕하세요. 오랫만에 블로그에 글을 올립니다. 지난번 Visual Studio Camp에서 옴니버스 형식의 세미나로 Visual Studio 2010 Service Pack 1에 대하여 말씀을 드렸던 세션이 있는데, 발표 자료와 더불어서 Visual Studio 2010 SP1에 대한 간략한 소개를 위하여 글을 씁니다.


Visual Studio의 새 도움말 시스템

Visual Studio 2010 RTM 버전부터는 새로운 형태의 도움말 시스템이 도입되는데, 로컬 웹 서버를 통하여 도움말 컨텐츠가 제공되는 방식으로 이전의 Visual Studio 2005와 Visual Studio 2008에서 제공되던 방식과 다르게 제공됩니다. Visual Studio 2005와 Visual Studio 2008의 경우 자체 URI Scheme을 Windows Registry에 등록하고 이를 Internet Explorer를 통하여 탐색할 수 있도록 확장하는 방식이었습니다. 그러나 새로운 도움말 컬렉션을 추가하거나 삭제하는 과정에서 시스템 성능에 따라 재배열 시간이 상당히 오래 걸리는 문제가 있어 불편한 점도 있었습니다. 이러한 방식 대신 더 단순하지만 더 유연한 방식으로 바꾸게 된 듯 합니다.

그렇지만 이전 버전에서 제공되던 색인, 검색 기능 등이 웹 사이트 형식으로 바뀌면서 이전에 사용했던 기능들이 사라져서 아쉬운 점도 있었는데 이번 Service Pack 1에서는 다시 Help Browser Software가 부활했습니다. 그래서 로컬 웹 서버로 컨텐츠를 보여주는 것은 동일하지만 Visual Studio를 통해서 컨텐츠를 탐색하면 Help Browser가 별도로 나타납니다.

그리고 이번 도움말 시스템에서의 백미는 인터넷을 통한 업데이트가 가능해졌다는 점입니다. 실제로 설치한 적이 없는 제품이라 할지라도, 그리고 DVD를 통해서만 설치할 수 있는 전체 버전의 MSDN 안에서만 제공되던 컨텐츠까지도 인터넷을 통하여 항상 최신 버전을 다운로드받아 로컬 도움말 컬렉션에 추가하거나 필요하지 않으면 삭제할 수 있습니다.

Silverlight 4에 대한 지원 추가

Visual Studio 2010 SP1을 설치하면 별도로 Silverlight 4에 대한 Tools for Visual Studio를 추가 설치할 필요가 없습니다. Silverlight 4부터는 이전의 WPF보다 작지만 웹이 아닌 데스크탑 및 오프라인 환경에서 잘 동작하는 응용프로그램을 제작할 수 있는 기능이 더 완벽하게 제공됩니다. 이러한 기술 전반은 권한 상승이 적용된 실버라이트 응용프로그램에서 가능한 것이며, 여기에는 파일 입출력이나 로컬 COM 컴포넌트와 연계하는 방안이 포함되어있습니다. 아래의 예제는 권한 상승이 적용된 Silverlight 4 기반 응용프로그램 샘플의 소스 코드이며, 사용자 프로필 디렉터리 내의 "내 그림" 폴더에 있는 이미지들을 열거하고 뷰어를 통하여 보여주는 예제입니다.



위 프로그램의 소스 코드 중 파일 입출력에 대한 소스 코드를 실제로 발췌하면 다음과 같습니다.

private void UpdateFileList()
{
    string targetPath = Environment.GetFolderPath(
        Environment.SpecialFolder.MyPictures);
 
    List<object> content = new List<object>();
    foreach (string eachFile in Directory.EnumerateFiles(targetPath))
    {
        switch (System.IO.Path.GetExtension(eachFile).ToLower())
        {
            case ".jpg":
            case ".jpeg":
            case ".png":
                break;
 
            default:
                continue;
        }
 
        content.Add(eachFile);
    }
    this.fileList.ItemsSource = content;
}
Visual Studio 2010 SP1을 설치한 후 Silverlight 프로젝트를 생성하려고 하면 다음과 같이 대화 상자가 나타나는데 이 때 Silverlight 4를 사용하도록 지정하면 사용이 가능합니다.

IIS Express 7.5에 대한 지원 추가

Visual Studio 2005부터는 Cassini Web Server라고 불리던 ASP.NET Development Server를 통하여 전체 버전의 IIS가 없어도 쉽게 ASP.NET 응용프로그램을 테스트할 수 있는 환경이 제공되었습니다. 그러나 Visual Studio 2008의 등장과 더불어 IIS 역시 대폭 업그레이드되어 Windows Server 2008부터는 완전히 새로워진 아키텍처를 기반으로 하는 IIS 7이 등장하게 됩니다. 이에 따라, 어느 정도 호환성을 보장하기는 하지만 이전의 IIS와는 많이 달라졌기 때문에 Cassini Web Server 만으로는 테스트가 어려운 점이 많았습니다. 통합 IDE의 이점도 확보하고, 전체 버전의 IIS를 사용하지 않으면서도 충분히 모든 기능을 점검해볼 수 있는 방향으로 가기 위하여 IIS Express가 등장하게 됩니다.

IIS Express를 사용하는 것은 실제 IIS를 사용하는 것과 비교했을 때 다음과 같은 장점이 있습니다.

  • ASP.NET Development Server와는 달리 FastCGI 모듈을 호스팅할 수 있으므로 PHP와 같은 FastCGI 지원 웹 언어들을 같은 환경에서 동시에 테스트할 수 있습니다.
  • 웹 프로젝트에서 IIS를 사용하도록 지정한 경우, 관리자 권한을 얻을 수 없는 다른 컴퓨터에서는 웹 프로젝트를 열 수 없는 문제점이 있었으나 IIS Express를 사용하도록 하면 이런 제약이 없습니다.
  • IIS Hosted Core를 사용하므로 전체 버전의 IIS가 없어도 상관이 없으며, IIS Express가 설치되어있지 않은 경우 Visual Studio가 자동으로 이를 감지하여 Web Platform Installer를 호출하여 IIS Express가 설치될 수 있도록 해줍니다.
  • 개별 프로세스 형태로 실행되므로 여러 사람이 사용하는 컴퓨터에서도 시스템 설정을 편집하는 일 없이 안전하게 실행할 수 있습니다.

 

HTML 5와 CSS 3에 대한 문법 검증 지원

Visual Studio 2010 SP1 및 Visual Web Developer 2010 Express SP1을 설치하면 HTML 5, XHTML 5 및 CSS 3에 대한 지원이 기본으로 내장되어있어 정확한 코딩이 가능합니다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>HTML5 Test</title>
    <link type="text/css" rel="Stylesheet" href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.10/themes/redmond/jquery-ui.css" /> 
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.js"></script>
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.10/jquery-ui.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $('#test').dialog({ show: "drop", hide: "drop", width: "auto", height: "auto", title: "html 5 rocks!" }).show();
        });
    </script>
</head>
<body>
    <div id="test">
        <video src="demo.mp4" width="700" height="500" id="testVideo" autoplay="autoplay">
            <strong>Your web browser does not support video element.</strong>
        </video>
    </div>
</body>
</html>



위의 그림과 같이 검사할 문법을 지정하여 프로그래밍하면 꼭 지정해야 할 프로퍼티를 검사하여 경고를 띄우거나, 프로퍼티에 포함되어야 할 값의 유형을 자동으로 유추해주어 규칙을 몰라서 잘못 코딩할 가능성을 예방해 줍니다.

그 외에 눈여겨 볼만한 것들

Visual Studio 역시 최근에 급격한 변화를 맞이하고 있습니다. 빠르게 변화하는 기술을 수용하기 위해서 Internet Explorer의 런칭 주기가 짧아진 것과 비슷하게, Visual Studio 역시 자주 새로운 형태의 도구와 프레임워크를 업데이트하고 있으며, 이러한 노력의 일환으로 Express Edition의 가치가 더 높아지고 있습니다.

대표적으로 Visual Studio LightSwitch와 Visual Web Developer Express Edition, 그리고 Visual Studio for Windows Phone 7이 그 예시입니다. 전체 버전의 Visual Studio 제품 구성을 바꾸지 않고 안전하게 테스트해볼 수 있는 방법으로서도, 그리고 실무 개발 환경에서도 유용하게 쓰일 수 있습니다.

그러나 서비스 팩 출시와 더불어서 Express Edition의 경우 한 박자 정도 업데이트가 늦어지는 편입니다. 이 때문에, 먼저 설치한 서비스 팩과 나중에 설치한 RTM 버전의 Express Edition 사이의 버전 차로 인한 충돌 문제가 이슈가 되었던적이 있는데, 이번 버전부터는 그러한 상황이 있을 경우 Visual Studio가 시작되기 전에 해당 문제점을 사용자에게 정확히 알려줍니다. 그 외에, 다양한 도구와 런타임에서 기능 및 성능 향상이 있었습니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Visual Studio2011. 4. 14. 10:36

안녕하세요. 오랫만에 블로그에 글을 올립니다. 지난번 Visual Studio Camp에서 옴니버스 형식의 세미나로 Visual Studio 2010 Service Pack 1에 대하여 말씀을 드렸던 세션이 있는데, 발표 자료와 더불어서 Visual Studio 2010 SP1에 대한 간략한 소개를 위하여 글을 씁니다.


Visual Studio의 새 도움말 시스템

Visual Studio 2010 RTM 버전부터는 새로운 형태의 도움말 시스템이 도입되는데, 로컬 웹 서버를 통하여 도움말 컨텐츠가 제공되는 방식으로 이전의 Visual Studio 2005와 Visual Studio 2008에서 제공되던 방식과 다르게 제공됩니다. Visual Studio 2005와 Visual Studio 2008의 경우 자체 URI Scheme을 Windows Registry에 등록하고 이를 Internet Explorer를 통하여 탐색할 수 있도록 확장하는 방식이었습니다. 그러나 새로운 도움말 컬렉션을 추가하거나 삭제하는 과정에서 시스템 성능에 따라 재배열 시간이 상당히 오래 걸리는 문제가 있어 불편한 점도 있었습니다. 이러한 방식 대신 더 단순하지만 더 유연한 방식으로 바꾸게 된 듯 합니다.

그렇지만 이전 버전에서 제공되던 색인, 검색 기능 등이 웹 사이트 형식으로 바뀌면서 이전에 사용했던 기능들이 사라져서 아쉬운 점도 있었는데 이번 Service Pack 1에서는 다시 Help Browser Software가 부활했습니다. 그래서 로컬 웹 서버로 컨텐츠를 보여주는 것은 동일하지만 Visual Studio를 통해서 컨텐츠를 탐색하면 Help Browser가 별도로 나타납니다.

그리고 이번 도움말 시스템에서의 백미는 인터넷을 통한 업데이트가 가능해졌다는 점입니다. 실제로 설치한 적이 없는 제품이라 할지라도, 그리고 DVD를 통해서만 설치할 수 있는 전체 버전의 MSDN 안에서만 제공되던 컨텐츠까지도 인터넷을 통하여 항상 최신 버전을 다운로드받아 로컬 도움말 컬렉션에 추가하거나 필요하지 않으면 삭제할 수 있습니다.



Silverlight 4에 대한 지원 추가

Visual Studio 2010 SP1을 설치하면 별도로 Silverlight 4에 대한 Tools for Visual Studio를 추가 설치할 필요가 없습니다. Silverlight 4부터는 이전의 WPF보다 작지만 웹이 아닌 데스크탑 및 오프라인 환경에서 잘 동작하는 응용프로그램을 제작할 수 있는 기능이 더 완벽하게 제공됩니다. 이러한 기술 전반은 권한 상승이 적용된 실버라이트 응용프로그램에서 가능한 것이며, 여기에는 파일 입출력이나 로컬 COM 컴포넌트와 연계하는 방안이 포함되어있습니다. 아래의 예제는 권한 상승이 적용된 Silverlight 4 기반 응용프로그램 샘플의 소스 코드이며, 사용자 프로필 디렉터리 내의 "내 그림" 폴더에 있는 이미지들을 열거하고 뷰어를 통하여 보여주는 예제입니다.



위 프로그램의 소스 코드 중 파일 입출력에 대한 소스 코드를 실제로 발췌하면 다음과 같습니다.

private void UpdateFileList()
{
    string targetPath = Environment.GetFolderPath(
        Environment.SpecialFolder.MyPictures);
 
    List<object> content = new List<object>();
    foreach (string eachFile in Directory.EnumerateFiles(targetPath))
    {
        switch (System.IO.Path.GetExtension(eachFile).ToLower())
        {
            case ".jpg":
            case ".jpeg":
            case ".png":
                break;
 
            default:
                continue;
        }
 
        content.Add(eachFile);
    }
    this.fileList.ItemsSource = content;
}
Visual Studio 2010 SP1을 설치한 후 Silverlight 프로젝트를 생성하려고 하면 다음과 같이 대화 상자가 나타나는데 이 때 Silverlight 4를 사용하도록 지정하면 사용이 가능합니다.


IIS Express 7.5에 대한 지원 추가

Visual Studio 2005부터는 Cassini Web Server라고 불리던 ASP.NET Development Server를 통하여 전체 버전의 IIS가 없어도 쉽게 ASP.NET 응용프로그램을 테스트할 수 있는 환경이 제공되었습니다. 그러나 Visual Studio 2008의 등장과 더불어 IIS 역시 대폭 업그레이드되어 Windows Server 2008부터는 완전히 새로워진 아키텍처를 기반으로 하는 IIS 7이 등장하게 됩니다. 이에 따라, 어느 정도 호환성을 보장하기는 하지만 이전의 IIS와는 많이 달라졌기 때문에 Cassini Web Server 만으로는 테스트가 어려운 점이 많았습니다. 통합 IDE의 이점도 확보하고, 전체 버전의 IIS를 사용하지 않으면서도 충분히 모든 기능을 점검해볼 수 있는 방향으로 가기 위하여 IIS Express가 등장하게 됩니다.

IIS Express를 사용하는 것은 실제 IIS를 사용하는 것과 비교했을 때 다음과 같은 장점이 있습니다.

  • ASP.NET Development Server와는 달리 FastCGI 모듈을 호스팅할 수 있으므로 PHP와 같은 FastCGI 지원 웹 언어들을 같은 환경에서 동시에 테스트할 수 있습니다.
  • 웹 프로젝트에서 IIS를 사용하도록 지정한 경우, 관리자 권한을 얻을 수 없는 다른 컴퓨터에서는 웹 프로젝트를 열 수 없는 문제점이 있었으나 IIS Express를 사용하도록 하면 이런 제약이 없습니다.
  • IIS Hosted Core를 사용하므로 전체 버전의 IIS가 없어도 상관이 없으며, IIS Express가 설치되어있지 않은 경우 Visual Studio가 자동으로 이를 감지하여 Web Platform Installer를 호출하여 IIS Express가 설치될 수 있도록 해줍니다.
  • 개별 프로세스 형태로 실행되므로 여러 사람이 사용하는 컴퓨터에서도 시스템 설정을 편집하는 일 없이 안전하게 실행할 수 있습니다.

HTML 5와 CSS 3에 대한 문법 검증 지원

Visual Studio 2010 SP1 및 Visual Web Developer 2010 Express SP1을 설치하면 HTML 5, XHTML 5 및 CSS 3에 대한 지원이 기본으로 내장되어있어 정확한 코딩이 가능합니다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>HTML5 Test</title>
    <link type="text/css" rel="Stylesheet" href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.10/themes/redmond/jquery-ui.css" /> 
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.js"></script>
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.10/jquery-ui.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $('#test').dialog({ show: "drop", hide: "drop", width: "auto", height: "auto", title: "html 5 rocks!" }).show();
        });
    </script>
</head>
<body>
    <div id="test">
        <video src="demo.mp4" width="700" height="500" id="testVideo" autoplay="autoplay">
            <strong>Your web browser does not support video element.</strong>
        </video>
    </div>
</body>
</html>



위의 그림과 같이 검사할 문법을 지정하여 프로그래밍하면 꼭 지정해야 할 프로퍼티를 검사하여 경고를 띄우거나, 프로퍼티에 포함되어야 할 값의 유형을 자동으로 유추해주어 규칙을 몰라서 잘못 코딩할 가능성을 예방해 줍니다.

그 외에 눈여겨 볼만한 것들

Visual Studio 역시 최근에 급격한 변화를 맞이하고 있습니다. 빠르게 변화하는 기술을 수용하기 위해서 Internet Explorer의 런칭 주기가 짧아진 것과 비슷하게, Visual Studio 역시 자주 새로운 형태의 도구와 프레임워크를 업데이트하고 있으며, 이러한 노력의 일환으로 Express Edition의 가치가 더 높아지고 있습니다.

대표적으로 Visual Studio LightSwitch와 Visual Web Developer Express Edition, 그리고 Visual Studio for Windows Phone 7이 그 예시입니다. 전체 버전의 Visual Studio 제품 구성을 바꾸지 않고 안전하게 테스트해볼 수 있는 방법으로서도, 그리고 실무 개발 환경에서도 유용하게 쓰일 수 있습니다.

그러나 서비스 팩 출시와 더불어서 Express Edition의 경우 한 박자 정도 업데이트가 늦어지는 편입니다. 이 때문에, 먼저 설치한 서비스 팩과 나중에 설치한 RTM 버전의 Express Edition 사이의 버전 차로 인한 충돌 문제가 이슈가 되었던적이 있는데, 이번 버전부터는 그러한 상황이 있을 경우 Visual Studio가 시작되기 전에 해당 문제점을 사용자에게 정확히 알려줍니다. 그 외에, 다양한 도구와 런타임에서 기능 및 성능 향상이 있었습니다.
Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Exploring2011. 4. 2. 21:40

[Internet Explorer에 대한 내용을 정정하였습니다.]

이전부터 포터블 응용프로그램을 만들기 위한 시도는 많이 있었고 최근들어서는 이러한 시도들이 가상화 기술의 한 장르로 발전하게 되었습니다. 대표적으로 Thinstall이 과거에 있었는데 이 솔루션은 VMware ThinApp으로 재탄생했지요. 그리고 Microsoft 역시 App-V 기술을 제공하고 있습니다. 그런데 오늘은 이러한 응용프로그램 가상화 솔루션에 클라우드 기술, 그리고 적절한 사용자 인터페이스까지 결합한 해외 서비스 하나를 소개해볼까 합니다. 바로 roozz입니다.


roozz는 Firefox와 Google Chrome 브라우저에서 사용할 수 있는 전용 플러그인을 다운로드받아 설치하고, Application Feed 페이지를 방문하기만 하면, Application이 Windows 기반이었든, Linux 기반이었든 관계없이, 거기에 roozz 플러그인을 설치하고 실행하는 컴퓨터 역시 Windows이든 Linux이든 관계없이 가상화된 소프트웨어가 별도의 격리된 공간 안에서 실행됩니다. 뿐만 아니라, 응용프로그램 가상화를 기반으로 하기 때문에 3D 게임까지 지원됩니다.

제가 평소에 애용하는 개발 도구 중 하나인 LINQpad 역시 roozz에서 호스팅되는 응용프로그램 중 하나입니다. 시험 삼아서, roozz에서 호스팅되는 LINQpad를 직접 실행해보았습니다. 그리고 편의를 위하여, Google Chrome의 웹 어플리케이션 생성 기능을 LINQpad roozz feed page에 대해 적용하여 실행해보았습니다. 그 결과 아래와 같이, 마치 Native application과 같은 UI가 구현되는 것을 볼 수 있습니다.


.NET Framework를 사용하는 응용프로그램임에도, LINQ expression을 잘 실행하고 있는 것이 보입니다. .NET Framework 기반의 응용프로그램을 이와 같이 가상화를 통하여 원활하게 사용할 수 있다는 것은 Windows 개발자에게도 굉장한 메리트가 아닐 수 없습니다. 그런데 여기서 한 가지 궁금한 점이 생깁니다. 지금 이렇게 보는 화면이 원격지 서버의 화면을 기반으로 하는 것은 아닐까 하는 것이지요. 시험삼아서 파일 저장과 로드 기능을 테스트해보았습니다.


터미널 서비스나 Citrix Xen과 같은 VDI나 Remote Session 서비스와는 달리, 로컬 컴퓨터에 직접 저장하는 대화 상자가 나타납니다. 그리고 한 가지 더 확실한 증거가 있는데, 작업 관리자의 메모리 사용량을 보면 알 수 있습니다.


커서를 가져다 놓은 부분에서 알 수 있듯이, LINQpad 자체는 원격지가 아닌 현재 컴퓨터의 메모리를 사용하고 있습니다. 단, 응용프로그램 가상화를 기반으로 하므로 .NET Framework를 메모리에 올려서 사용하기 때문에 다소 메모리 사용량이 많은 것이 보입니다. 하지만, 메모리 사용량과는 별개로 이러한 수준의 기능을 제공할 수 있는 서비스라고 한다면 상당히 괜찮지 않을까 생각합니다.

roozz에 이와 같이 소프트웨어를 게시할 수 있는 방법은, 소스 코드가 아닌, 컴파일된 - 혹은 - 패키징된 소프트웨어 사본을 roozz에 전송하는 것입니다. 이렇게 전송된 사본은 roozz Conversion Tool에 의하여 재배포 가능한 형태로 구성되며 이것을 사용자가 받아볼 수 있는 형태로 게시됩니다. 좀 더 자세한 내용은 http://www.roozz.com/node/3 에서 확인할 수 있습니다.

Roozz로 게시된 LINQpad를 사용해보시려면, Google Chrome이나 Firefox로 아래 웹 사이트를 방문해 보시면 됩니다. 최초에 Roozz Plugin을 설치한 후 페이지를 새로 고치면 됩니다. 아쉽게도, 현재 Internet Explorer는 지원되지 않는다고 합니다. Internet Explorer의 경우 보호 모드때문에 roozz 플러그인이 곧바로 실행되지는 않으며, 적어도 신뢰할 수 있는 사이트 목록에 http://prod.roozz.com 을 추가한 이후에야 아래와 같이 동작합니다. Internet Explorer 9에서도 잘 동작합니다. :-)

http://prod.roozz.com/apps/61/LINQPad.htm

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2011. 3. 29. 00:21

이전 글: [Windows Azure Platform/A Lap around Cloud Computing] - A Lap around cloud computing – 지금이 여러분의 이력서를 새로 쓸 시간 

뜬금없이 근두운 이야기가 무엇인가 하고 놀라는 분들이 있으리라 생각한다. 이해가 빠른 분들이 계실 것이므로 단도직입적으로 말하면, 필자가 의도한 그대로, Cloud Computing 이야기를 하고자 했던 것이다. 우리의 머릿속 한 구석에 큰 존재감을 과시하며 차지하고 있는 전설 속 원숭이 손오공의 근두운을 IT 세상에서는 누구나 하나씩 다 가지고 있는 것이다.

여러분이 사용하고 싶어하는 근두운의 종류 또한 다양하다. 그래서 앞서 설명했던 Windows Live, Windows Server 기반 Private Cloud, Office 365가 있었고, 오늘은 마지막으로 개발자와 IT 전문가들의 관점에서 적극적으로 검토해 볼 가치가 있고 든든한 파트너 역을 맡아줄 Windows Azure Platform이라는 근두운을 이야기해볼 생각이다.

IT 관리자의 관점에서 보는 Windows Azure Platform

PDC08에서 처음 소개된 Windows Azure Platform은 전적으로 개발자의 역할을 중시했던 플랫폼이었다. 이는 PDC09, 그리고 PDC 2010 직전까지도 지속되었고 꾸준히 그 색을 더해 나가고 있던 과정이었다. 하지만 PDC 2010에서 처음으로 세간에 루머로만 떠돌던 VM Role이 공식적으로 사용 가능하게 베타 서비스로 출시되었고 이에 따라 IT 관리자들의 관점에서도 Windows Azure Platform을 활용할 수 있는 기회가 대폭 늘어나게 되었다.

Windows Azure Platform이 IT 관리자들에게 제공하는 주요 이점은 한 마디로 정리하면 기존의 IT 자산과 맞물려 사용할 수 있는 다양한 기회를 제공한다는 점이다. Microsoft의 Public Cloud는 모든 것을 Cloud로 올려야 한다고 말하지 않는다. 대신, 네트워크 수준에서의 통합부터 시작하여 Cloud 내부 및 외부에서 발생할 수 있는 문제를 다양한 방법으로 해결할 수 있도록 도와준다.

Windows Azure의 VM Role은 On-Premise 시스템을 분리 해체하는 작업을 거치지 않고 곧바로 Windows Azure 데이터센터에 서버를 올려놓는 방법이다. 기존에 먼저 소개된 Web Role 및 Worker Role과 달리 Windows Server 2008 R2 운영 체제 전체를 하나의 완전한 Role로 채택하여 사용할 수 있는 기법으로, 여러분이 기존에 어떤 라이선스를 가지고 있던지 관계없이 Windows Azure VM Role 라이선스로 전환할 수 있도록 해준다.

매우 이상적인 이야기처럼 들릴 수도 있지만 사실 중요한 문제가 두 가지가 있다. 라이선스에 관한 것이 있고, 또 다른 하나는 기술적인 구성 상의 문제이다. 다음의 표에 대략적인 내용을 언급해두었다.

구성 요소 및 역할

변경 방향

3rd Party Software

Plan A: Public Cloud 호환 라이선스로 재계약

Plan B: 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합 / 단 Traffic 추가로 인한 변동 사항은 해당 공급자와 재 협상 필요

3rd Party Software Data

SQL Server Embedded DB

è MDF 및 LDF 파일을 SQL Server에 연결하고, 해당 DB를 SQL Azure로 이관해야 함

è MDB 파일이나 ACCDB 파일의 경우 SQL Server로 이관 후 SQL Azure로 이관해야 함

기타 데이터베이스

è 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합

SQL Server

Plan A: SQL Azure로 부분/전체 Migration

Plan B: 관계 지향적이지 않고 대용량 DB가 필요한 경우 Windows Azure Table Storage 사용

Plan C: 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합

Exchange Server

Plan A: Office 365로 부분/전체 Migration

Plan B: 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합

SharePoint Online

Plan A: Office 365로 부분/전체 Migration

Plan B: 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합

Lync Online

Plan A: Office 365로 부분/전체 Migration

Plan B: 기존 서버를 유지하고, Windows Azure Connect로 네트워크 통합

Active Directory

AD DS, AD LDS 모두 기존의 On-Premise 시스템을 Windows Azure Connect를 경유하여 활용하는 것이 최선

 

라이선스에 관한 문제의 본질은 다음과 같다. Windows Azure Compute를 통해서 서비스가 실행되면, Service Level Agreement (SLA) 계약 이행을 위하여 기본적으로 VM을 1대 이상 사용하는 것을 전제로 한다. 최소 1대만을 유지하도록 설정해도 상관은 없지만, 필연적으로 사용량이 증가하고 서비스를 위하여 배치된 VM들의 상태가 바빠지는 것이 감지되면 자동적으로 Fabric Controller가 원본 VM 이미지를 복제하여 새로운 VM을 복제하기 시작한다. 이것이 의미하는 바는 단순하다. 물리적인 Instance의 수가 자동으로 늘어나므로 그 안에 포함된 3rd Party 소프트웨어에 대한 라이선스도 같이 계산되어야 하고, 그것이 CPU 기반 라이선스이든 연결 개수 기반 라이선스이든 상관이 없는 것이다. 양쪽 라이선스 모두 있는 그대로 (as-is) 해석을 한다면 Public Cloud 내에서는 상식을 넘는 금액을 요구할 수 밖에 없다.

이를 해결하기 위해서는 해당 소프트웨어 공급자가 Public Cloud에 대응되는 사용량 – 또는 – 사용 시간 기반 라이선스를 지원해야 하며, 대다수의 경우 이를 지원하지 않을 것이므로 이러한 소프트웨어를 포함하는 서버를 On-Premise 환경에 배치하고, 이들 서버에 대한 종속성을 지니는 별도의 VM Role, Web Role, Worker Role 만을 Windows Azure에 게시한 후 Windows Azure Connect로 상호 연동을 가능하게 만드는 것이 최선이다.

기술적인 문제의 본질은 다음과 같다. 주로 데이터베이스에 대한 부분과 관련이 깊은데, Windows Azure가 SLA 이행을 위하여 VM을 복제하고, 복제된 VM들의 목록을 기준으로 Load Balancer를 구현하는 것은 매우 바람직한 일이다. 그러나 기존의 서버 모델은 개별 서버가 데이터베이스까지 서버 내에 같이 포함하고 있는 경우가 많은데 여기에 대한 적당한 조치를 취하지 않고 그대로 VM Role로 전환하는 경우 우스꽝스러운 문제가 발생한다. 접속할 때 마다 데이터베이스의 내용이 달라지는 일이 발생하는 것이다. 이를 해결하기 위해서는 사용 중인 데이터베이스의 종류를 파악하는 것이 중요한데, SQL Server로 이관이 가능한 범주 안에 있는 데이터베이스들은 우선 SQL Server로 이관한 후, 이를 SQL Azure로 다시 이관하는 작업이 필요하다. 그리고 기존 응용프로그램들도 SQL Azure를 데이터 소스로 사용할 수 있도록 일부 수정이 필요하다.

SQL Azure로 이관하는 것을 누구나 쉽게 검토해볼 수는 있다. 그러나 생각 외로 만만찮은 문제들이 쌓여있다. 기존에 사용하던 자료 형식 중 CHAR, VARCHAR, TEXT와 같이 유니코드와 호환되지 않는 문자열 자료 형식들은 이관 후 CJK 문자 세트로 구성된 데이터가 소실되므로 NCHAR, NVARCHAR, NTEXT로 업그레이드해야 한다는 부분이 있다. 날짜와 시간의 경우 이관 이전과 이관 이후의 시간대 설정 차이가 있으므로 데이터 일관성에 문제가 있을 수 있다는 점이다. 드문 경우이지만, .NET 어셈블리는 SQL Azure에 설치할 수 없으므로 이와 관련된 기능을 사용하는 경우 SQL Azure로 이관하기 전 적당한 Wrapper나 Agent를 따로 개발해야 한다. 또, 기존의 응용프로그램이 데이터베이스 연결을 헤프게 사용하는 경향이 있다면 SQL Azure 입장에서는 예고 없이 연결을 차단시킬 수 있다는 점도 숙지해야 한다. SQL Azure 서비스 자체는 공유 환경에서 실행되므로 SQL Server 인프라와는 비교할 수 없이 엄격한 정책 준수를 요구하는데, 사실 이 때문에 낭패를 보는 경우가 많다. 이런 모든 문제들을 극복하기 위해서, 데이터베이스 역시 특별한 이슈가 없다면 Windows Azure Connect를 사용하여 기존 On-Premise 환경과 구분선 없이 밀착시키는 것이 좋을 수 있다.

사실 지금 언급한 내용들만 이야기해도 Cloud로 이관하는 것보다는 이관하지 않는 것이 더 좋은 것처럼 들린다. 그래서, IT 관리자 입장에서는 무리해서 기존의 인프라를 Cloud로 이관하기 보다, 기존의 인프라나 IT 자산으로는 충당할 수 없는 새로운 영역을 Cloud를 통해 개발하고 확보하는 방법을 새로 익히는 것이 좋다. 그런 맥락에서, IT 관리자들은 Cloud 환경에 최적화된 VM-Role을 개발하는 방법을 익히고, VM-Role이 Windows Azure Connect를 통하여 기존의 Active Directory Domain Controller에 참가하도록 시스템을 구성하거나, 웹 상에서의 클레임 기반 인증을 구현할 목적으로 Active Directory Federation Services (AD FS)와 Windows Azure AppFabric Access Control을 같이 활용하는 방안을 모색하는 것이 바람직하다.

응용프로그램 개발자 관점에서 보는 Windows Azure

원래부터 그러했지만 Windows Azure는 개발자들을 위한 Cloud 플랫폼이었다. 여러 서비스들이 있지만 각각의 역할을 하나씩 소개하려 한다.

Windows Azure Compute: Windows Azure 데이터센터에서 여러분의 응용프로그램을 Hosting할 수 있도록 해주며, IIS를 활용하여 웹 응용프로그램을 실행할 수 있도록 해주는 Web Role, WCF, Socket, C, C++, Python 등 Win32 기반 시스템에서 사용 가능한 모든 종류의 응용프로그램을 실행할 수 있도록 해주는 Worker Role, 그리고 VHD 기반 이미지를 이용하여 Windows Server 2008 R2 OS를 실행할 수 있도록 해주는 VM Role을 하나의 서비스 안에서 다양한 방법으로 조합하여 실행할 수 있는 서비스이다. Windows Azure SDK에서는 VM Role을 제외한 Web Role과 Worker Role 에뮬레이터가 기본 제공된다.

Windows Azure Storage: 대용량의 데이터를 고속으로 처리할 수 있도록 해주는 특별한 저장소로, HTTP 및 HTTPS 프로토콜을 기반으로 상호 작용할 수 있기 때문에 플랫폼이나 위치에 제약이 없다. 저장소의 유형으로는, 단순 파일 저장 및 대용량 파일의 Paging 연산을 지원하는 BLOB 저장소, 행과 열의 대규모 집합 및 고속 인덱싱을 지원하는 테이블 저장소, 고속 메시지 입력 및 출력을 지원하는 큐 저장소로 구분된다. 저장소의 범주에 속하지는 않으나, Windows Azure Compute 상의 Role들이 Win32 API를 사용하여 파일 입력과 출력 연산을 수행할 수 있도록 해주는 Cloud Drive API가 Windows Azure Storage Emulator와 함께 제공된다.

Windows Azure CDN: 대한민국 및 아시아 권역에서 빠른 속도를 자랑하는 새로운 CDN 서비스 역시 Windows Azure Platform 안에 있다. 기본적으로는 Windows Azure Blob Storage에서 공개 권한으로 설정한 Block BLOB에 대해 CDN 서비스를 사용할 경우 자동으로 Mirroring이 된다. 최근 업데이트에서는 Windows Azure Storage가 아닌, 동적으로 API를 사용하여 특정 Contents를 CDN 서비스를 통해 Mirroring할 수 있게 업데이트되었고, 더불어 HTTPS도 지원하기 시작하였다.

Windows Azure AppFabric: 대규모 서비스 운영에 필요한 주요 서비스 컴포넌트 5가지를 제공하는 온라인 서비스로, Windows Server AppFabric의 기술을 바탕으로 하지만 외부에 드러나는 모습은 많이 다르다.

Windows Azure 초창기부터 지속적으로 제공되어왔던 Service Bus는 Point-to-Point 연결을 구현하는 Tunneling Mechanism을 제공한다. WCF 기술을 기반으로 하며, 서버 역할을 수행하는 WCF 호스트가 Service Bus와 연결을 맺은 뒤, WCF 클라이언트는 직접 WCF 호스트에 접근하지 않는 대신, 암호화된 연결을 사용하는 Service Bus로 방향을 바꾸어 접속을 시도하는 방식이다. 이러한 방식이 유용한 이유는, 방화벽의 존재 여부와 관계없이 네트워크 계층에 일관성이 없는 서로 다른 환경 사이를 완벽하게 연결시켜주기 때문이다.

Access Control 서비스는 또 한 번 업데이트를 준비 중에 있다. 처음 발표된 Access Control은 특정 도메인이나 기관이 운영하는 Active Directory 인프라를 기반으로 인터넷 상에서 클레임 기반 인증을 구현하기 위한 목적으로 처음 소개되었다. 인터넷 서비스를 상대로 클레임 기반 인증을 수행하는 것이기 때문에, 인트라넷 환경과는 달리 수시로 Traffic이 발생하며, 뿐만 아니라 신뢰성도 매우 중요하기 때문에 Azure AppFabric Access Control이 유용하다. 그리고 조만간 대대적인 업데이트를 통하여 Windows Live ID, Yahoo, Google, Facebook 등의 Social Networking Platform을 인증 수단으로 사용할 수 있게 되어 한층 더 폭넓은 활용 가능성을 제공한다.

Cache 서비스는 Server 버전의 AppFabric Cache를 Cloud 버전으로 제공하는 것으로, Cache를 위한 인프라를 직접 구축하지 않으면서, 같은 API, 같은 기술을 사용할 수 있는 것이 장점이다. Windows Azure Storage와 SQL Azure를 AppFabric Cache 원본으로 지정하여 사용할 경우 시간과 비용을 획기적으로 절약할 수 있다. 그리고 올해 연중으로 BizTalk Server와의 연계를 고려한 AppFabric Integration 서비스와 함께 Cloud Computing 전반을 통솔하고 제어할 수 있는 AppFabric Composite App 역시 출시될 예정에 있다.

물론 아직 부족한 서비스들도 있다. 그렇지만 이 정도 수준의 서비스라고 한다면 누구나 원하는 서비스를 제약 없이 구현해 볼 수 있지 않을까? 프로그래밍 언어나 개발 도구에 관계없이, 그리고 여러분이 실행하는 프로그램의 위치와 무관하게 말이다. 다시 강조하지만, Microsoft의 Public Cloud는 다른 Cloud Platform들처럼 강제 이주를 논하지 않는다. 모든 것은 여러분의 결정에 따라 움직이며, 매번 적절한 솔루션은 Microsoft에 의해서이든 오픈 소스 커뮤니티에 의해서이든 쓰여지고 업그레이드되어 나가고 있다. Microsoft가 말하는 Cloud Power의 진가를 확인하고 싶다면 지금 곧 Windows Azure Platform으로 떠나보자.

더 많은 정보가 필요하다면 Windows Azure 홈페이지 (http://www.windowsazure.com/)와 더불어 Windows Azure Café (http://cafe.naver.com/wazure), 그리고 .NET 기반 소프트웨어 개발을 위하여 Visual Studio 2010 한국 공식 팀 블로그 (http://www.vsts2010.net/)을 자주 찾아주기 바란다.

글쓴이 이력

  • Blog: http://www.rkttu.com / E-MAIL: rkttu@rkttu.com / Twitter: @rkttu
  • Windows Azure MVP (2011) / Visual C# MVP (2009-2010)
  • ㈜코아뱅크 코아기술연구소 (http://www.corebank.net) 연구원 재직 중
  • Windows Azure Café SYSOP (http://cafe.naver.com/wazure)
  • Visual Studio 2010 Team Blog (http://www.vsts2010.net) 집필진 활동 중
Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

이벤트2011. 3. 25. 22:05

세미나 등록 : http://onoffmix.com/event/2600

스마트한 당신은 진정한 VS 2010의 개발자입니다.Visual Studio 2010 IDE를 이용한 유용한 도구 모음과 사용, 그리고 Visual Studio 개발자를 위한 앱스토어 “Visual Studio 온라인 갤러리”에서 개발자들에게 유용한 도구와 기능을 소개합니다

Visual Studio 공식 팀 세미나

- 주최 : 한국Visual Studio 공식 팀
- 일시 :2011 4 6일 수요일
- 시간 : 늦은 오후 7 30 ~ 9 30
- 장소 : 한국 Microsoft Korea 5
- 참가비 : 무료
- 경품 : 삼성동 코엑스 바이킹 뷔페 식권 3

세미나 아젠다

시간

발표자

제목

730~ 735

강성재 차장

VS 2010 개발자 앱스토어 Introduction

735 ~ 750

남정현MVP

VS 2010 Service pack 1 소개

7 50 ~ 8 10

강보람MVP

VS 2010 PowerTools

8 10 ~ 8 20

엄준일MVP

VS 2010 성능 프로파일러

8 20 ~ 8 30

휴식

8 30 ~ 8 50

김병진MVP

P&P 설계 구성하기

8 50 ~ 9 10

오태겸

WCF템플릿과 사용하기

9 10 ~ 9 30

박종혁

VS TFS 2010 Power Tools 업그레이드

경품추첨

섹션 내용

VS 2010 Service pack 1 소개


3
8일 이제 Visual Studio 2010 Service pack1이 발표되었습니다. 이번 Service pack1에 포함된 주요 내용을 알아보고 업데이트를 고민하는 개발자의 고민을 해결해 줄 것입니다

VS 2010 PowerTools


Visual Studio 2010 IDE
만 잘 써도 Smart 한 개발자가 될 수 있습니다. Microsoft 에서 개발자들을 위한 무료앱 천국에 있는 VS 2010 Power Tools에 대한 궁금증을 풀어드립니다.

VS 2010 성능 프로파일러


Visual Studio
에서 개발한 프로그램에 대한 성능을 알수 있을까? ~ 이제 Visual Studio 성능 프로파일러를 이용한 성능 검증에 대한 내용을 알아봅니다.

P&P 설계 구성하기


설계? 이건 어려운 거야 너무 힘들어?

아닙니다. 이제Microsoft 개발자 앱 스토어와 P&P에서 제공하는 무료 템플릿을 이용하면 쉽게 여러분들도 설계를 할 수 있습니다

WCF템플릿과 사용하기


WCF?
이거 그냥 구현하면 되는데. 그런데.. REST 서비스는? 이제 걱정하지 마십시요. Microsoft 갤러리에서 WCF 템플릿에 추가된 REST 서비스 템플릿을 이용하면 쉽게 WCF REST 서비스를 개발할 수 있는 환경을 제공합니다.

VS TFS 2010 Power Tools 업그레이드


Visual Studio Team Foundation Server
관리가 어려우시나요? 아 지긋지긋한 백업 ㅠㅠ DB도 해야하고 SharePoint도 해야하고 너무힘드셨죠? 이제 Power Tools에서 한번에 해결하십시요.

경품

코엑스 오크우드 호텔 뷔페 레스토랑 바이킹 식권 3(1 1인입니다)


세미나 등록 :
http://onoffmix.com/event/2600

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

발표 자료 공유2011. 3. 17. 18:24

올해에도 어김없이 Microsoft TechDays가 찾아왔습니다. 올해 봄 시즌에는 "N 스크린 시대의 IT 전문가들을 위한 온라인 컨퍼런스"라는 주제로 여러 Microsoft MVP들의 온라인 세션이 준비되어있습니다. 그리고, 지금 한창 진행 중인 Imagine Cup 2011 한국 대표 선발전과 더불어서, IT 기술을 통하여 실력을 업그레이드하기도 하고, 전 세계의 수많은 대학생들과 아이디어로 경진해볼 수 있는 Imagine Cup에 대한 상세한 소개도 온라인 세션으로 같이 준비되어있습니다.

이번에도 여러 세션들이 있지만 오늘 제가 소개해드리려고 하는 세션은 개발 - 또는 - Microsoft N 스크린 개발에 처음 입문하시는 분들을 위한 내용, 그리고 모바일, 클라우드, 이매진컵에 대한 내용들을 따로 발췌하여 찾아보시기 편하도록 블로그 포스팅을 재구성해 보았습니다.

개발에 처음 입문하시는 분들께 추천해드립니다.
* Visual Studio 2010 How To Start : 개발자를 꿈꾸는 분들을 위한 입문서 - (주)코아뱅크 연구원 남정현 / Windows Azure MVP
* N-스크린 시대의 필수 Agile 개발 : 1부 모바일 - 강보람 Visual C# MVP
* N-스크린 시대의 필수 Agile 개발 : 2부 WEB - 유니위스 박세식 대리
* N-스크린 시대의 필수 Agile 개발 : 3부 클라이언트 - 엄준일 Visual Studio ALM MVP

Windows Phone 7 개발에 입문하시는 분들께 추천해드립니다.
* 모다의 Windows Phone 뚝딱 팩토리 1. 헬로우 Windows Phone - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 2. 실버라이트, Windows Phone 을 만드는 기술! - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 3. Windows Phone 의 얼굴 만들기, UI - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 4. 인터넷, Windows Phone 과손을 잡다 - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 5. 데이터 바인딩의 기초 - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 6. 우리 하드디스크가 달라졌어요, 격리된 저장소 - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 7. 메뉴? 아니죠, 어플리케이션 바? 맞습니다 - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 8. 어플리케이션 속으로 들어간 인터넷 익스플로러 - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 9. Where am I? - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 10. 레이싱 게임의 핸들을 구현하는 기술, 가속도계 - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 11. 꼭꼭 숨어라 데이터가 보인다 - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 12. 잠시 대출(?)이 가능한 기술들, 카메라/주소록/이메일.. - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 13. 다양한 상황에 따라 모양이 변하는 터치 키보드 - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 14. LINQ를 이용한 간단한 실전 예제! 블로그 보기 - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 15. 손가락이 하나 더 늘어나면? 멀티터치! - 한국 Microsoft 홍준모 Evangelist Intern
* 모다의 Windows Phone 뚝딱 팩토리 16. 앱 속의 미디어 플레이어 - 한국 Microsoft 홍준모 Evangelist Intern

Windows Azure 개발에 입문하시는 분들께 추천해드립니다.
* 클라우드 응용 프로그램 개발 - Ty Anderson VSTO MVP
* Windows Azure에서 클라우드 응용 프로그램 개발 시작하기 - Hilton Giesenow MVP
* Windows Azure에서 클라우드 응용 프로그램 처음 만들기 - Hilton Giesenow MVP
* SQL Azure : SQL Azure를 사용하여 데이터 액세스를 포함한 클라우드 응용 프로그램 만들기 - Hilton Giesenow MVP
* Windows Azure 현재와 미래 - 한국마이크로소프트 박중석 개발자 에반젤리스트
* Windows Azure 보안 - 한국마이크로소프트 박중석 개발자 에반젤리스트
* Windows Azure 비용 - 한국마이크로소프트 박중석 개발자 에반젤리스트
* Windows Azure 성능 - 한국마이크로소프트 박중석 개발자 에반젤리스트
* 해외 실제 사례로 살펴보는 마이크로소프트 클라우드 개발 - 한국마이크로소프트 박중석 개발자 에반젤리스트
* 마이크로소프트 클라우드 기술 방향성 - 한국마이크로소프트 박중석 개발자 에반젤리스트

Imagine Cup을 준비하시는 분들께, 그리고 대학생 여러분들께 추천해드립니다.
* Imagine Cup : 세상의 난제를 IT기술로 해결하라! - 홍익대학교 황채영 MSP,한국마이크로소프트 최은지 DPE Intern
* Windows Live Mesh 2011 : 동기화 되는 삶  - 프리랜서 박광수 MSP&MVP
* Microsoft Expression Studio 4 : 협력 툴의 결정체 - 프리랜서 노희상 MSP
* Web Matrix : 나만의 블로그를 쉽게 만드는 방법 - 한국기술교육대학교 허찬 MSP, 성신여자대학교 이서연 MSP

더 많은 내용을 보시려면 http://www.techdays.co.kr/2011Spring/ 페이지를 방문해주세요. :-)
Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

  1. 동영상 잘 보았습니다!!
    N-Screen 개발, 재밌네요. ;)

    2011.03.19 02:08 신고 [ ADDR : EDIT/ DEL : REPLY ]

포트폴리오2011. 3. 2. 23:59

0123


지난번에 소개드렸었던 QRCODE 소셜 앱에 이어, 이번에는 좀 더 다양하고 편리한 기능들을 바탕으로, 그리고 Windows Azure Platform을 기반으로 소셜 앱을 새롭게 업그레이드 런칭하였습니다. 이번 버전에서는 좀 더 다양한 QRCODE 리더 응용프로그램과 상호작용하고, iPhone과 Android 버전 CASEQRCODE Reader App을 설치하시면 일정 관리 등의 기능도 QRCODE를 이용하여 관리하실 수 있습니다.

체험하러 바로 가기 (싸이월드/네이트온 로그인이 필요합니다.)
http://appstore.nate.com/Main/View?apps_no=1376

이번 버전에서 제일 많은 비중을 두고 사용된 것은 Windows Azure Platform의 상호 운용성 기술에 대한 부분으로, Compute의 경우 내부 역할이 2개의 역할로 구성되어있습니다. 앱 스토어에 올라갈 실버라이트 애플리케이션이 호출할 백그라운드 서비스와 더불어, iPhone과 Android 버전 CASEQRCODE Reader App과 상호작용할 REST 기반 API를 호스팅하는 Web Role이 있으며, Java JSP를 기반으로 작성된 QRCODE Image Rendering을 위한 Apache Tomcat 기반의 Worker Role이 있습니다. 그리고 이 둘 사이를 중계하기 위하여 사용자가 직접 업로드하는 이미지들은 물론, 생성되는 QR 코드를 보관하기 위한 Windows Azure Storage가 있으며, SQL Azure를 Web Role과 Worker Role에서 모두 사용합니다. 그리고 실버라이트의 경우, 빠른 다운로드 속도를 제공할 수 있도록 Windows Azure Storage에 현재 게시하였으며 필요한 경우 CDN으로 전환하는 것을 검토 중에 있습니다.

이번 Social App을 런칭하기까지 많은 분들의 기술적 도움과 자문을 바탕으로 성공적으로 Cloud Application을 런칭할 수 있었습니다. 이번에 쌓인 노하우를 다양한 자리에서 다양한 방법으로 전달하고, 또한 많은 발전을 할 수 있도록 노력하고자 합니다. 이번 런칭에 많은 격려와 조언을 아낌없이 해주신 SHESTORY의 김의준 사장님께도 깊은 감사를 드립니다.

감사합니다. :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2011. 2. 27. 16:40

다음 글: [Windows Azure Platform/A Lap around Cloud Computing] - A Lap around cloud computing – 1인 1근두운 시대
이전 글: [Windows Azure Platform/A Lap around Cloud Computing] - A Lap around Cloud Computing – 당신이 어디에 있든 관계없는 세상

이력서 안 고친지 꽤 지났는데……

지난 글에서는 Windows Live, Live@edu, Office 365를 통하여 사람들이 가정에서, 학교에서, 그리고 직장에서 Cloud Computing과 어떻게 친하게 지낼 수 있는지를 살펴보았다. 오늘은 기업 내에서 충실하게 제 몫을 다하고 있는 전산 자원들을 Cloud Computing 환경에 맞도록 업그레이드시키기 위한 방법인 가상화에 대하여 살펴보려고 한다. 가상화는 Cloud Computing의 한 축을 이루는 중요한 기술이다.

일각에서는 Cloud Computing의 도래를 두고, Microsoft나 유명 IT 기업들만의 잔치판이 될 것이므로 기업 내에서 일하는 모든 IT 전문가와 개발자들이 스스로 사표를 내도록 종용 당하게 만들 것이라고 좌절하는 목소리가 심심치 않게 들려온다. 그러나 필자의 생각은 다르다. 오히려 이전보다 더 뛰어나고 완벽한 IT 기술을 필요로 하게 될 것이며, 한 층 더 자동화되고 지능적인 시스템과 같이 일할 수 있도록 해야 하며, 사실 지금이 바로 열심히 여러분의 이력서의 새 버전을 작성해야 할 때인 것이다.

가상화에 대한 이해

이 글을 읽는 독자 대다수는 집에서 여러분의 배우자나 어머님께서 설거지하시는 모습을 잘 기억하고 있을 것이다. 그릇을 닦기 위하여 수세미를 사용하고, 그릇에 묻어있는 기름기를 걷어내기 위하여 매직 블록을 조각 내어 주방 세제에 묻혀 사용하는 그런 모습 말이다. 필자는 서버 가상화를 설명하는데 이보다 더 좋은 소재는 없다고 생각한다.

방금 이야기한대로 서버 가상화는 멀티 코어로 확장되는 엄청난 성능의 서버 컴퓨터를 효율적으로 사용할 수 있도록 도와주는 매우 똑똑한 전략이다. 매직 블록을 통으로 다 쓰는 것보다는, 잘게 조각 내어 여러 차례 필요한 만큼 사용하는 것이 더 오래 쓰고 좋은 세척 능력을 보여준다. 이전과는 다르게 서버 컴퓨터도 이러한 방법으로 나누어 쓰는 것이 대세인 시대가 되었다. 그렇지만 이를 어떻게 나누고 관리할 것인가?

응용프로그램 개발자들에게 있어서 이 질문에 대한 답은 병렬 프로그래밍 기법이다. 병렬 프로그래밍 그 자체는 이전부터 계속 사용이 가능했던 기법이었지만 최근에 중요한 변화를 맞이하게 되었다. 병렬 프로그래밍은 엄밀히 말하면 사람이 인지하기 어려울 정도로 빠른 속도로 사용자가 컴퓨터에게 지시하여 형성한 문맥들을 회전하면서 작업을 처리하는 것으로, CPU의 발전 과정과 연계를 지어보면 쉽게 이해할 수 있다. 초창기의 CPU들은 회전의 빠르기를 뜻하는 주파수가 높지 않았기 때문에 많은 작업을 할 수 없었지만, 어느 순간에 이르러서는 단일 CPU가 GHz 단위까지 주파수를 높여서 만족스러운 성능을 보여주기도 하였다. 그러나 속도가 아무리 빠르다 한들 결국 문맥들 사이를 전환할 수 있는 성능 상의 임계는 변치 않기 때문에 이를 원점에서 극복할 수 있도록 다중 CPU의 시장 진출이 활성화된 것이다. 이에 따라 여러 개의 CPU를 기본적으로 운영 체제의 재량에 따라 활용할 수 있는 기회가 생겼고, 응용프로그램 개발자들에게도 같은 기회가 주어진 셈이다.

서버 가상화는 여기에서 출발한다. 운영 체제가 사용자에게 제공할 수 있는 병렬 연산은 두 가지로 볼 수 있는데, 비교적 실행 시간이 짧거나 유한한 범위 내에서 작업이 완료될 수 있는 알고리즘의 병렬화를 커버하기 위한 Multithread 연산은 개발자들을 위한 영역이다. 그러나 유한한 시간 내에 종결되는 작업이 아닌, 독립적인 세션을 만들어서 운영하는 방법도 필요했는데 그것이 가상화 기술이다. 초창기의 가상화 기술은 Emulation에 가까웠던 것으로 다른 시스템의 동작을 모방하여 특정 프로그램이나 동작을 재현하는 경우가 많았다. 그러나 시간이 흐를수록 좀 더 실용적으로 가상화 기술을 개발하기 시작하여 실제로 사용할 수 있는 형태로 만들기 시작하여 현재의 가상화 기술에 이르게 되었다. 이러한 가상화 기술을 Hypervisor라고 하며, 우리가 흔히 이해하는 것은 Type 2의 개념이고, 요즈음 주목을 받는 것은 Type 1의 개념이다.

Type 1과 Type 2 사이의 차이점은 한 마디로, 가상화 기술을 사용자에게 서비스하는 관점의 차이이다. Type 2의 경우 사용자는 가상화 기술을 하나의 하위 응용프로그램으로 보는 구조이고, Type 1은 가상화 기술로 생성된 다수의 독립적인 서브 시스템 앞에 사용자가 한 명 이상 접근하는 구조이다.

사실 Type 1의 Hypervisor 자체는 1960년대부터 지속적으로 개발해온 시스템이지만, 일부 고가의 하드웨어에 한정되는 사양이었기 때문에 많은 관심을 받지 못하였다. 뿐만 아니라 일반 PC에서 이를 구현하기에는 성능도 부족하였고, 또한 일반 PC에서 실행되는 운영 체제의 전부를 Type 1의 가상화를 구현하는 데에 모두 바치는 것 또한 굉장한 낭비였기 때문이다. 그러나 PC 및 Workstation Computer의 사양이 드디어 이런 기능을 구현하기에 충분한 수준까지 이르게 되면서 다시금 주목 받게 된 것이다.

가상화를 구현하는 방법에 있어서는 전 가상화와 반 가상화로 나눌 수 있는데 전 가상화는 동일한 아키텍처의 시스템을 하나의 격리된 영역에서 다시 구축하는 것을 말하는데, CPU, BIOS 등 가장 하단에 위치하는 하드웨어까지 Emulation을 하는 것을 말한다. 가상화를 통하여 모든 운영 체제를 완전히 독립적으로 실행할 수 있는 것은 이런 사양을 전제로 하기 때문이다. 그러나 전 가상화 이외에도 호스트 시스템과의 상호작용, 연동 제어 등의 요구 사항이 실제로는 더 필요했기 때문에 가상과 실제 사이의 경계를 가로지를 수 있는 인터페이스가 필요한데 이를 반 가상화를 통하여 구현하고, 반 가상화 기술을 통하여 가상 환경 상의 성능 저하를 개선하는 경우도 있다. 즉, 현실과 타협한 것이 반 가상화에 의한 구현인 셈이다.

반 가상화를 구현하는 방법은 가상화 기술 제조 업체마다 차이가 많지만, 호스트 운영 체제를 처음부터 가상화 기술을 잘 수용할 수 있도록 개조하는 방법이 있고, 기본 목적을 유지하면서 확장된 아키텍처를 수용할 수 있도록 확장하는 방법이 있는데, Microsoft의 Hyper-V는 후자에 속하는 방법을 제공한다. 뿐만 아니라 Windows Server Core 환경 위에도 Hyper-V Hosting 기능을 제공하여 호스트 컴퓨터가 외부 네트워크에 노출되는 표면적을 최소화하고 안정성을 보장하는 기법을 구상하는 것 역시 다른 오픈 소스 플랫폼들과 마찬가지로 가능하다. 기존에 구매한 Windows Server 인프라를 버리고 중복 투자할 필요 없이, 약간의 방법 터득 만으로도 충분히 만족스러운 Private Cloud를 구현할 준비가 이미 되어있는 것이다. 그러므로 부디 멀리 떠나지 말자.

IT 전문가들은 가상화로 무엇을 어떻게 할 것인가?

가상화 기술로 시스템을 분할하고 나면 그 다음에는 무엇을 할 것인가? 이 질문에 대해 IT 전문가들이 찾을 수 있는 방안은 시스템 구성 복잡도의 감소, 빠른 테스트 환경 구축, 가상 데스크톱 인프라 구축으로 분류할 수 있다.

서버를 한 대 이상, 여러 대를 배치할 수 있는 전산 환경에서는 한 서버에 1개 이상의 역할을 맡기지 않지만 현실적인 이유와 비용 상의 문제 때문에 이런 규칙은 쉽게 깨진다. 가상화를 이용하여 시스템을 나눈다면 이 규칙을 다시금 당연하게 받아들일 수 있게 될 것이다. 여기에, 게스트로 사용하려는 서버 운영 체제가 Windows Server 2008에 해당하는 경우 테스트 환경까지 자동화할 수 있는 혜택도 덤으로 얻는다. Windows AIK를 사용하여 자동 응답 파일을 만들 수 있고, 이렇게 만들어진 자동 응답 파일을 WIM2VHD와 같은 도구에 매개 변수로 지정하여 Windows 설치 디스크 이미지를 곧바로 부팅 가능한 가상 하드 디스크로 Provisioning하는 것뿐만 아니라 기초 설정까지 단번에 Customizing하는 것이 가능하다.

이렇게 만들어진 원본 가상 하드 디스크를 기점으로 차이점 보관 디스크 등을 사용하여 가상 하드 디스크들을 버전 관리할 수 있으므로 각종 업데이트와 Hotfix 설치에 민감하게 반응하는 시스템을 가상화해야 하는 경우 이는 매우 이상적인 환경이 아닐 수 없다. 이러한 작업들을 Private Cloud Computing 환경에 알맞게 솔루션 차원에서 도와주는 것이 바로 System Center Virtual Machine Manager이며, 관리자가 수작업으로 이러한 과정을 수행하지 않고 Active Directory 인프라를 이용하여 인증부터 시스템 Provisioning까지 웹 상에서 처리할 수 있도록 돕는 것이 SCVMM Self Service Portal이다.

가상 데스크톱 인프라는 앞서 설명한 기술들로 갖추어진 인프라를 이용하여 종전에 널리 사용되었던 터미널 서비스가 결합되어 완성된다. 종전의 터미널 서비스에서 보여지던 것은 동일하게 구성된 서버들 사이를 라운드 로빈 등의 알고리즘을 이용하여 연결을 분산시키고, 사용자가 응용프로그램을 빌려 쓰는 방식이었다. 반면 VDI는 응용프로그램 대여가 아닌 가상 PC 전체를 완전히 특정 사용자에게 임대하는 방식이기 때문에 VDI로 만족할만한 성과를 얻을 수 있으려면 얼마나 빠르게 VDI용 가상 PC를 Provisioning할 수 있는지도 관건이 된다. 뿐만 아니라, 이런 식으로 만들어진 가상 PC들에 대한 최신 업데이트와 보안 점검을 수행하기 위해서는 종전에 잘 알려진 WSUS나 Forefront를 쉽게 제어할 수 있는 System Center 솔루션 전반이 역시나 필요하다.

지금 언급한 사항들만 대충 살펴보더라도 관리자가 가상화나 Private Cloud 기술 때문에 직업을 잃어버리기는커녕 한층 더 복잡하고 높은 수준의 기술에 대한 이해가 필요함을 알 수 있다. Microsoft VDI에 대한 전반적인 Overview 및 Licensing 정보를 살펴보려면 아래의 동영상을 살펴보기 바란다.



http://www.microsoft.com/showcase/en/us/details/9291a982-2f32-4d25-84bb-671accbcb002

그리고 여기에 여러분들은 한 가지 더 이점을 얻을 수 있다. Windows 7 SP1과 Windows Server 2008 R2 SP1의 출시와 더불어서 가상 컴퓨터 상의 게스트 운영 체제들의 성능을 미리 계산된 불연속적인 값에 의한 설정이 아닌, 연속적이고 유동적으로 변경 가능한 설정으로 재 구성이 가능한 Dynamic Memory 기능과 더불어, 다소 비싼 하드웨어를 필요로 하지만 Remote Session을 경유하더라도 3D 그래픽과 렌더링을 경험할 수 있는 RemoteFX 기술 지원까지 가능하게되어 한 층 더 높은 활용도를 제공한다. Windows 7 SP1과 Windows Server 2008 R2 SP1은 지금 Windows Update를 통하여 업데이트가 가능하며, 기술적인 상세 정보는 http://blogs.technet.com/b/koalra/archive/2011/02/10/windows-7-windows-server-2008-r2-1-rtm.aspx 의 내용을 확인하기 바란다.

개발자들은 가상화로 무엇을 할 것인가?

개발자들에게도 가상화는 작업하는 방법에 많은 변화를 가져다 준다. 그 중에서도 테스트 과정에 지대한 영향을 가져다 준다. 가상화를 통해서 가장 먼저 수혜를 누리는 것은 바로 Mobile 및 Embedded 장치 개발이다. 원칙적으로, Mobile과 Embedded 장치를 대상으로 응용프로그램을 개발하기 위해서는 개발자 당 1대 이상의 실제 장치가 필요한 것이 당연하다. 하지만, 앞에서 언급한 전 가상화 기술을 통해서 Intel CPU가 아닌 Mobile 장치의 CPU를 Emulation하여 약간의 제한 사항이 있지만 기본적인 테스트에는 문제가 없도록 해주는 테스트 및 디버깅 환경을 완성시켜준다. 이는 Windows Mobile 6.x, Windows Phone 7, Windows Embedded Compact 7을 통해서 쉽게 경험할 수 있었던 부분들이다.

그러나 한 발 더 나아가서, 테스트와 디버깅을 실제 Windows 운영 체제에서도 실행할 수 있어야 하고, 테스트 주도 개발 (TDD) 방법론에 입각하여 테스트를 수행하고, 확실한 QA를 수행하여 개발자와 직접 상호 작용할 수 있는 개발 방법론을 구현할 수 있도록 하려면 그 다음은 무엇이 필요할까? 답은 Visual Studio 2010 Ultimate부터 제공되는 Test Lab Management이다.

Test Lab Management는 내부적으로 SCVMM와 Hyper-V를 사용하여 테스트 환경을 구축하게 되며, Team Foundation Services (TFS) 영역 내에서 관리되는 프로젝트와 통합되어 자동 및 수동 테스트 케이스에 따라 테스트를 진행하고 Screenshot과 같은 일차원적인 정보 수집 말고도 시스템 상태, 문제가 발생했던 시점의 Stack Trace 기록은 물론 변수 상태까지 기록하여 데이터베이스로 저장하는 IntelliTrace 로그 수집까지 처리한다. 필요한 모든 주변 정황들이 소프트웨어 통제 환경 아래에 놓이게 되므로 재현 불가능한 버그가 나타나지 않도록 도와준다. 아래의 동영상은 Test Lab Management로 실제로 QA를 진행하는 과정을 보여주는 Overview 동영상이며 한 번 재미 삼아 보기를 권한다.




http://msdn.microsoft.com/en-us/vstudio/ff945982

다음 시간에는

기본적으로 가상화를 통하여 일상적인 시스템 관리 작업 및 테스트 작업들을 소프트웨어가 서 있는 땅 아래로 가져다 놓고 모든 것을 Top-Down으로 관리하는 것이 이루려고 하는 목표이다. 이전에 언급하였던 대로, 개념적으로는 간단할 수 있지만, 이러한 작업들을 성공적으로 수행할 수 있으려면 적어도 규모에 관계없이 여러분이 완전히 제어하고 통솔할 수 있는 데이터 센터의 소유와 IT 전문가, 그리고 개발자들을 필요로 한다. 그리고 이런 환경을 가지고 있든, 가지고 있지 않든 진정으로 뛰어난 성능을 필요로 하고, 비즈니스의 핵심 가치에 집중하기를 원한다면, 다음 시간에 언급할 Windows Azure Platform으로의 이동을 바로 지금 준비할 때이다.

처음 Windows Azure Platform이 발표된 이후부터 지금 이 순간까지 많은 변화가 있었고, 지난 PDC'10에서 발표된 업데이트에는 IT 전문가들이 Private Cloud 뿐만 아니라 Public Cloud에서도 역량을 펼칠 수 있도록 도와주는 Windows Azure Connect 및 Virtual Machine Role이 발표되었다. 앞으로 2회 연재에 걸쳐서 Windows Azure Platform이 IT 전문가들과 개발자들에게 어떤 변화를 가져다 줄 수 있는지 더 살펴보려고 한다.

글쓴이 이력

  • Blog: http://www.rkttu.com / E-MAIL: rkttu@rkttu.com / Twitter: @rkttu
  • Windows Azure MVP (2011) / Visual C# MVP (2009-2010)
  • ㈜코아뱅크 코아기술연구소 (http://www.corebank.net) 연구원 재직 중
  • Windows Azure Café SYSOP (http://cafe.naver.com/wazure)
  • Visual Studio 2010 Team Blog (http://www.vsts2010.net) 집필진 활동 중
Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

PaaS2011. 2. 25. 10:36

안녕하세요. Windows Azure MVP 남정현입니다. 이제 2월도 얼마 남지 않았네요. 2011년을 새로운 마음으로 맞이하고나서 정말 빠르게 시간이 흐르는것 같습니다. 오늘은 Windows Azure를 좀 더 쉽고 간편하게 경험할 수 있는 방법을 소개해드리기 위하여 글을 올립니다.

Windows Azure Virtual Lab

이전에 특정 프로그래밍 언어나 Windows Server 제품군, 또는 실버라이트 개발 등을 위하여 Virtual Lab으로 미리 학습을 해보신 적이 있으신가요? Microsoft는 가상화 기술을 이용하여 인터넷 상에서 누구나 무료로 Microsoft의 최신 기술을 컴퓨터에 추가적인 소프트웨어를 설치하지 않고서도 테스트해볼 수 있는 Virtual Lab을 운영합니다. 단순히 테스트 환경만 제공하는 것이 아니라 구체적인 실습 가이드 라인을 통하여 자습할 수 있도록 도와줍니다. Windows Azure Virtual Lab의 컨텐츠는 계속 업데이트되고 있으며 이 글을 올리는 현 시점에서 다음의 Virtual Lab이 제공됩니다.

  • MSDN Virtual Lab: Windows Azure Native Code
  • MSDN Virtual Lab: Building Windows Azure Services with PHP
  • MSDN Virtual Lab: Getting Started with Windows Azure Storage
  • MSDN Virtual Lab: Building Windows Azure Services
  • MSDN Virtual Lab: Using Windows Azure Tables
  • 실제 Windows Azure 계정을 제공하는 것은 아니며, Visual Studio 및 Windows Azure Tools for Visual Studio가 미리 설치된 가상 PC 환경을 제공하는 것입니다. 업데이트되는 전체 Virtual Lab 컨텐츠를 보시려면 http://msdn.microsoft.com/en-us/dd540819 페이지를 방문하시면 되겠습니다.

    Posted by Cloud Developer 남정현 (rkttu.com)

    댓글을 달아 주세요

    발표 자료 공유2011. 2. 24. 01:52

    CODEPARTY 2011년 2월 / 세션 1 발표 자료 공유합니다. 삼성 소프트웨어멤버십의 조수현 회원님과 세션을 진행하였으며, 당일 세션 2에서는 삼성 소프트웨어멤버십 회원이자 Microsoft Client App Dev MVP로 활동 중이신 김현중 MVP님, 그리고 삼성소프트웨어멤버십 회원으로 활동 중이신 진성주 회원님께서 세션을 진행하여 주셨습니다. 세미나에 참석해주신 모든 분들께 감사드리며, 앞으로 Windows Azure Cafe 차원에서 더욱 다양하고 알찬 정보를 전달할 수 있도록 노력하겠습니다. 감사합니다. :-)


    Posted by Cloud Developer 남정현 (rkttu.com)

    댓글을 달아 주세요

    PaaS2011. 2. 17. 16:37

    인터넷 검색 중에 아주 흥미로운 웹 캐스트를 하나 발견하였습니다. 닷넷 기반 응용프로그램 프레임워크 전문 개발 업체인 DevForce를 기반으로 하는 Prism Explorer와 이에 연관된 Northwind 샘플 데이터베이스를 기초로 하는 엔터프라이즈 응용프로그램을 Windows Azure Platform의 Windows Azure Compute와 SQL Azure Database로 마이그레이션하는 웹 캐스트입니다. 기본적으로 이 동영상은 DevForce 프레임워크의 클라우드에서의 활용 가능성 및 실리성을 설명하기도 하지만, 동시에 Windows Azure Platform에 대한 실질적인 예를 들어주는 좋은 사례라 생각하여 블로그에 백서와 동영상에 대한 링크를 첨부하였습니다.

    백서 다운로드 (English Only): http://www.ideablade.com/PDF/DevForceInAzure.pdf
    동영상 출처 (English Only): http://www.ideablade.com/Videos/PrismExToAzure/
    홈페이지: http://www.ideablade.com/DevForceProductPlatform/DevForceInAzure.aspx

    Posted by Cloud Developer 남정현 (rkttu.com)

    댓글을 달아 주세요

    발표 자료 공유2011. 2. 17. 01:37
    실전 Cloud App 분석 세미나 발표 자료 공유합니다. (2010년 겨울 인하대학교 하이테크에서 진행한 세미나)


    Posted by Cloud Developer 남정현 (rkttu.com)

    댓글을 달아 주세요

    1. 고맙습니다. 다운로드해갑니다. :)

      2011.02.24 10:06 신고 [ ADDR : EDIT/ DEL : REPLY ]

    발표 자료 공유2011. 2. 17. 01:16

    이번 2011년 2월 CODE PARTY 세미나에서는 개발자들을 위한 Windows Azure Platform에 대한 전반적인 Overview와 개발 방법론, 그리고 다양한 실전 사례들을 살펴볼 예정입니다. Client Application Development MVP이신 김현중 MVP님과 삼성소프트웨어멤버십에서 활동 중이고 클라우드 어플리케이션 경진 대회 금상 및 바다 어플리케이션 챌린지 수상에 빛나는 진성주 회원님과 같이 2시간 동안 삼성동 포스코센터 서관 5층에서, 2011년 2월 23일 수요일 저녁 7시부터 세미나가 진행될 예정입니다. 관심있으신 분들의 많은 참여와 홍보 부탁드립니다.


    세미나 등록 바로 가기: http://new.imaso.co.kr/seminar_inquiries/add/cp13

    Posted by Cloud Developer 남정현 (rkttu.com)

    댓글을 달아 주세요