Phalanger 공식 웹 사이트에서 따로 소개된 적은 없지만, Phalanger와 웹 매트릭스는 아주 이상적인 궁합을 보여주고 있으며 Phalanger가 보여주고자 하는 모습을 가감없이 완벽하게 보여줍니다. 이 아티클을 다 읽고 나면 지금 말하는 것이 어떤 의미인지 알게 될 것입니다.

Phalanger 설치하기

우선 컴퓨터에 Phalanger를 설치해야 합니다. 이전 아티클에서 이야기한대로 Phalanger는 .NET Framework 4.0을 필요로 합니다. 그리고 지금 우리가 실습하려는 WebMatrix도 설치해야 하는데, 결론적으로 지금 이야기하는 도구와 프레임워크들은 한 번에 Microsoft /web 홈페이지에서 제공하는 Web Platform Installer를 이용하여 한 번에 설치할 수 있습니다. http://www.microsoft.com/web 에서 WPI를 설치하고 WebMatrix와 .NET Framework 4.0을 선택하여 설치를 진행하도록 합니다. Phalanger를 설명하는 과정에서는 필요없지만, C#이나 VB.NET을 같이 사용하려고 한다면 Visual Web Developer 2010 Express도 설치합니다.

기본 구성 요소 설치가 끝나면 http://www.codeplex.com/phalanger에서 최신 버전의 Phalanger 설치 프로그램을 다운로드하여 설치를 시작합니다. Phalanger 설치 프로그램 안에는 런타임과 Visual Studio 도구가 모두 들어있습니다. 웹 개발에는 Visual Studio 도구가 따로 필요하지 않으며, Phalanger를 이용해서 PHP/PEAR와 같은 응용프로그램 개발을 하기 원한다면 Visual Studio 도구를 사용하는 것이 편합니다.

WebMatrix에서 Phalanger 사용하기

기본적으로 WebMatrix는 PHP4와 PHP5를 지원합니다. 그러나 WebMatrix가 기본으로 제공하는 PHP 런타임은 사용하지 않고 앞 단계에서 설치한 Phalanger 런타임을 대신 불러오도록 설정을 업데이트할 것입니다. 그러면서도, 기존의 PHP 개발 템플릿을 그대로 이용할 수 있습니다.

WebMatrix에서 Phalanger를 사용하는 방법은 간단합니다. 여러분이 원하는대로 사이트를 하나 새로 만들고, 사이트 탭을 클릭하고 설정 메뉴를 클릭하면 아래와 같이 화면이 나타납니다. 그림에 적은 설명대로, .NET Framework는 버전 4.0을 사용해야 하며, PHP 설정은 사용하지 않고, 필요하다면 index.php가 기본 페이지로 지정되도록 합니다.

이제 파일 탭을 클릭하고 F5키를 눌러 web.config 파일이 있는지 확인합니다. 만약 없다면 web.config 파일을 새 파일로 하나 추가합니다. web.config 템플릿이 WebMatrix에 기본으로 제공되므로 쉽게 추가할 수 있을 것입니다.

참고로 web.config은 기존의 ASP.NET 환경에서도 쓰이지만 WebMatrix가 내부적으로 서버로 사용하는 IIS 7 Express 및 IIS 7의 설정 파일로도 사용되며, IIS 6 이하에서 사용하던 메타베이스 기반 설정과는 달리 Apache HTTP Server의 httpd.conf와 같은 맥락의 디렉터리 단위 설정 파일이라고 보면 되겠습니다.

web.config 파일을 열어서 <system.webServer> XML 요소 아래의 내용을 수정해야 합니다. (다른 부분이 있더라도 여기서는 필요하지 않습니다.) 아래의 내용을 추가하여 PHP 확장자에 대한 지원을 추가하도록 합니다.

<handlers>
  <add name="PhalangerHandler" path="*.php" verb="*" type="PHP.Core.RequestHandler, PhpNetCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=0a8e8c4c76728c71" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>

파일을 저장하고, 잘 작동하는지 테스트하기 위하여 index.php 파일을 만들고 아래와 같이 코드를 작성합니다. 그리고 상단의 실행 버튼을 눌러 잘 나타나는지 확인합니다.

<?php

class myClass {
    var $x;
}

$test = new myClass();
$test->x = "Hello, World! in ";
print $test->x.'<br />';
print get_class($test);

phpinfo();

?>

그러면 아래와 같이 화면이 나타날 것입니다. 클래스를 선언하고, 변수 필드를 선언하고, 여기에 값을 대입하거나 print 문을 사용하여 문자열을 출력하고, get_class 같은 간단한 형식 조회 함수도 씁니다. 아, 그리고 phpinfo 함수는 PHP 세계에서는 매우 기초적이고도 기본적인 함수였죠. :-)

그리고 흔히 사용하는 include_once 같은 API도 잘 작동합니다. 같은 디렉터리 상에 test.php를 만들고 class 선언만 따로 떼어 저장한 다음 include_once 함수를 호출해보기 바랍니다.

test.php

<?php
class myClass {
    var $x;
}

?>

index.php

<?php

include_once('test.php');

$test = new myClass();
$test->x = "Hello, World! in ";
print $test->x.'<br />';
print get_class($test);

phpinfo();

?>

Phalanger에서 한글을 사용하려면

PHP4나 PHP5와 다를바 없는 실행 모습입니다. 그런데 한 가지 점검해봐야 할 것이 있습니다. Phalanger에서 한국어나 일본어같은 2바이트 문자를 정상적으로 취급할 수 있을까요? 기본 설정으로는 그렇지 않을 가능성이 있습니다. 그리고 웹 매트릭스는 모든 파일을 UTF-8로 저장하기 때문에 문제가 됩니다. 이러한 문제를 예방하기 위해서는 반드시 web.config 설정을 변경해야 합니다.

<system.web> 요소 아래에 다음의 코드를 추가하도록 합니다.

<globalization requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="utf-8" />

그리고 앞의 코드에서 한국어 문자열을 포함하는 print 명령문을 한 번 더 추가하여 한글이 잘 나오는지 확인합니다.

이제 Phalanger를 WebMatrix에서 개발할 준비는 다 끝났습니다. 다음 아티클에서는 Phalanger만의 고유한 기술적 특징을 살펴보면서, Phalanger를 C#과 VB.NET과 함께 사용하는 방법을 살펴보도록 하겠습니다. :-)

저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License

'Web Development > Phalanger' 카테고리의 다른 글

Phalanger와 PHP의 차이점들  (0) 2012/02/10
PHP x C# x VB.NET = ASP.NET  (0) 2012/02/08
Phalanger와 WebMatrix의 완벽한 만남  (1) 2012/02/06
PHP와 .NET의 완벽한 만남 - Phalanger  (0) 2012/02/04
Posted by Windows Azure MVP 남정현 (rkttu.com)

그 동안 .NET은 ASP.NET을 통해서 개발하는 것이 가장 최선이었고 실제로도 많은 개발 프로젝트는 ASP.NET 웹 폼을 통해서 진행되어왔습니다. 그리고 당연한 이야기이지만 PHP와 .NET은 전혀 다른 도메인에 속해있던 분리된 환경이었고, 그저 IIS를 통해서 호스팅 가능한 서로 다른 응용프로그램 도메인 상의 환경일 뿐이었습니다.

그러나 최근에 아주 흥미롭고 참신한 발견을 다시 했는데, 그간 베타 수준에만 머물러있던 Phalanger의 꾸준한 버전 업그레이드를 통해서 올해 1월에 3.0 버전을 발표했습니다. 64비트 시스템에 대한 지원도 충실히 하고 있으며, PHP의 태생적 한계로 자주 지목된 성능 상의 문제도 .NET 런타임을 사용하기로 하였기 때문에 구조적으로 해결하고 있으며, 무엇보다도 중요한 것은 엄격하게 PHP의 문법을 준수한다는 전제 아래에서 PHP 코드를 사용할 수 있다는 점입니다.

ps. Phalanger의 발음은 '팔란저'라고 하면 됩니다. 뜻은 '여우 원숭이'입니다.

Phalanger 프로젝트의 주요 기능은 다음과 같습니다.

PHP를 .NET 환경의 주요 프로그래밍 언어로 사용 가능하게 만듭니다.
* PHP 언어를 .NET CLR에서 사용 가능한 MSIL로 컴파일합니다.
* .NET 객체를 직접 PHP/CLR 언어 확장을 통해서 곧바로 사용할 수 있습니다.
* C#, VB.NET 등의 .NET 프로그래밍 환경에서 기존 PHP 코드 기반 라이브러리를 재사용할 수 있습니다.

기존 PHP 응용프로그램의 실행 속도를 향상시킵니다.
* 기존의 많은 수의 PHP 응용프로그램을 컴파일할 수 있습니다.
* Just-in-Time (JIT) 컴필레이션을 통해서 실행 속도를 개선할 수 있습니다.
* 표준 PHP 라이브러리 함수들과 네이티브 PHP4 확장 플러그인들을 그대로 사용할 수 있습니다.

PHP/CLR 확장을 통해서 PHP의 기능을 확장할 수 있습니다.
* PHP/CLR을 통해서 기존의 .NET CTS 시스템과 완벽하게 연동할 수 있습니다.
* PHP/CLR 프로젝트에 기존의 C#, VB.NET, C++ CLR 등으로 작성한 코드의 네임스페이스를 불러올 수 있습니다.
* PHP 언어로 .NET 제네릭 형식을 불러오거나 제작할 수 있습니다.
* .NET 커스텀 어트리뷰트, 부분 클래스, 프로퍼티 등 주요 기능들을 지원합니다.

PHP 언어로 .NET 라이브러리를 만듭니다.
* .NET/Mono 어셈블리에 맞추어 PHP 스크립트를 직접 DLL로 컴파일할 수 있습니다.
* Pure Mode를 사용하면 네이티브 코드에 의존하지 않는 완전한 .NET 환경에 맞출 수 있습니다.
* Legacy Mode를 사용하면 기존 PHP4/PHP5와의 호환성을 유지하면서도 .NET 환경에 맞출 수 있습니다.

PHP 프로젝트에서 .NET 라이브러리를 사용할 수 있습니다.
* C#이나 VB.NET으로 작성한 비즈니스 로직 위에 PHP를 표현 수단으로 채택할 수 있습니다.
* Phalanger를 통해서 기존에 작성한 어떤 종류의 .NET 객체이더라도 PHP에서 사용할 수 있습니다.
* ASP.NET 2.0 멤버십 API를 Phalanger 기반 PHP와 ASP.NET 모두에 적용할 수 있습니다.

PHP 언어를 Visual Studio에 통합할 수 있습니다.
* 프로젝트 템플릿, 문법 하이라이트, 디버거를 설치할 수 있습니다.
* 이를 통하여 Windows Forms, Console, Simple Win32 App을 만들 수 있습니다.

미리 이야기할 것이 하나 더 있는데 안타깝게도, Phalanger가 지원하는 PHP 문법은 기존의 PHP 문법과 완벽하게 일치하는 것이 아닙니다. 그래서 Phalanger를 기존의 PHP와 완벽하게 동일한 집합이나 기술로 보는 것은 다소 무리가 있으며, 대신 기존에 여러분이 알고 있던 PHP를 .NET 환경에서 그대로 쓸 수 있다는 사실에 집중하는 것이 바람직합니다.

개인적으로 Phalanger를 테스트하기에 가장 이상적인 환경은 WebMatrix인 것 같습니다. 다음 아티클에서는 Phalanger를 설치하고 WebMatrix위에 Phalanger로 PHP 코드를 작성하는 방법을 소개하도록 하겠습니다.

저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License

'Web Development > Phalanger' 카테고리의 다른 글

Phalanger와 PHP의 차이점들  (0) 2012/02/10
PHP x C# x VB.NET = ASP.NET  (0) 2012/02/08
Phalanger와 WebMatrix의 완벽한 만남  (1) 2012/02/06
PHP와 .NET의 완벽한 만남 - Phalanger  (0) 2012/02/04
Posted by Windows Azure MVP 남정현 (rkttu.com)

Hello .NET Framework 4 세미나 Part 2 발표 자료 및 샘플 소스 코드 올립니다. Part 1 및 Part 3에 대한 발표 자료 - 또는 - 샘플 소스 코드는 이번 주중에 모두 공개가 완료될 예정입니다. :-)

세미나 참가 신청 바로가기: http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=324&MAEULNo=28&no=1260

세미나 참가 신청 바로가기: http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=324&MAEULNo=28&no=1260

저작자 표시 비영리 동일 조건 변경 허락
이 장소를 Daum지도에서 확인해보세요.
서울특별시 강남구 대치4동 | 포스코센터
도움말 Daum 지도
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

많은 Windows Azure Application 개발자들의 피드백을 수용한 최신 버전의 Windows Azure Tools for Visual Studio와 Windows Azure SDK가 새롭게 출시되었습니다. 이제 비로소 Visual Studio 2010의 모든 기능을 Windows Azure 개발에도 직접 활용할 수 있게 되었습니다.

Windows Azure SDK 1.2에서는 최근 발표된 .NET Framework 4.0 런타임을 내장한 Windows Azure OS 2010년 4월 버전에 대한 요구 사항을 모두 반영하고 있습니다. .NET Framework 4.0 기반의 응용프로그램을 작성 중이신 분들도 이제는 Windows Azure 환경 위에서 직접 응용프로그램을 호스팅할 수 있습니다. 그리고, Visual Studio 2010에서 새로 추가된 향상된 디버깅 기법인 IntelliTrace를 직접 지원하기 때문에 이전보다 더욱 쉬운 디버깅이 가능합니다.

다음은 Windows Azure Tools for Visual Studio 1.2의 변경 사항들입니다.

  • Visual Studio 2010 RTM 지원: Visual Studio 2010 RTM 버전을 지원합니다.
  • .NET Framework 4.0 지원: 이제는 .NET Framework 3.5와 4.0을 빌드 타겟으로 동시에 지정할 수 있습니다. 단, 4.0을 빌드 타겟으로 지정하게 되는 경우, Windows Azure OS의 이미지 중 2010년 초반의 일부 버전은 사용할 수 없습니다.
  • Cloud storage explorer 추가: 읽기 전용 기능이 지원되는 Windows Azure Table 및 BLOB 컨테이너 보기 프로그램이 서버 탐색기 패널을 통하여 제공됩니다. SQL Azure를 데이터베이스 목록에 추가하고 동시에 관리할 수 있어 편리합니다.
  • 통합 배포 환경: 솔루션 탐색기에서 Windows Azure 프로젝트를 오른쪽 버튼으로 클릭하여 'Publish' 메뉴를 클릭하면 이제는 직접 배포가 가능합니다. 이전 1.0 및 1.1 버전의 경우, CSPKG 파일과 CSCFG 파일이 생성된 디렉터리의 폴더가 Windows 탐색기에서 열리고, Windows Azure Portal Web Site가 웹 브라우저로 열렸기 때문에, 브라우저에서 로그인하고 여러 단계에 걸쳐서 배포할 파일을 찾아가야했기 때문에 Deploy 절차가 복잡했습니다.
  • 서비스 모니터링: 서비스의 상태를 웹 제어판이 아닌 "서버 탐색기"의 compute 노드에서 실시간으로 모니터링할 수 있습니다.
  • IntelliTrace 기능 지원: Visual Studio 2010을 사용하는 경우, IntelliTrace 기능을 Windows Azure 서비스에 배포한 이후에 "직접" 사용할 수 있습니다. 이 기능은 앞에서 설명한 통합 배포 환경의 일부로 동작하며, 배포가 끝난 이후에 자동으로 이 기능이 시작되어 서비스 모니터링과 함께 실시간으로 로그가 모니터링됩니다.

그간 Windows Azure 기반의 개발이 어려우셨다면 이제는 최신 버전의 SDK와 개발 도구를 이용하여 좀 더 편안하게 Visual Studio 2010을 통해 클라우드 기반 응용프로그램 개발을 시작해보세요. 참고로 Visual Studio 2010의 데이터베이스 탐색기는 SQL Azure 데이터베이스에 대한 탐색도 지원하므로 이전처럼 별도의 SSMSE를 필요로 하지 않습니다. 그리고 이번 버전의 SDK 역시 1.0과 1.1과 마찬 가지로 처음 설치하는 경우에는 OS와 개발 도구의 환경에 따라 패치와 핫 픽스들을 적용하셔야 합니다.

다운로드 바로가기

 

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

.NET Framework 4.0과 Visual Studio 2010 RTM이 긴 테스트 과정과 수렴 과정 끝에 이번달에 성공적으로 전 세계에 런칭하였습니다. 생산성을 극적으로 업그레이드할 수 있는 다양한 기술과 API 들을 중무장하고, ASP.NET MVC2나 MEF (Managed Extensibility Framework) 등의 새로운 기술들도 다채롭게 선보였습니다.

 

그런데 한 가지 궁금증이 생깁니다. Windows Azure OS 자체는 아직도 .NET Framework 3.5 SP1을 기반으로 하는데 언제 .NET Framework 4.0으로 업데이트하는걸까요? 이에 대한 포럼 내의 답이 있어서 블로그에 소개합니다.

 

출처: http://www.mygreatwindowsazureidea.com/forums/34192-windows-azure-feature-voting/suggestions/395925-create-a-beta-environment-for-net-4-0-tests-and?ref=title

 

MIX2010에서, Windows Azure에서의 .NET Framework 4.0 지원은, RTM 버전이 공개된 이후 약 90일 이내에 업데이트된다고 합니다. 개발 과정 상의 변수 (Visual Studio용 SDK 개발, Windows Azure VM 이미지 업데이트) 등을 모두 감안한 기간으로 보입니다만, 늦어도 올해 초여름에는 .NET Framework 4.0을 기반으로 실행되는 Windows Azure 서비스를 사용할 수 있는 셈이 됩니다.

 

그렇지만, 좀 더 빠르게 .NET Framework 4.0 기반의 클라우드 응용프로그램을 개발하고 테스트하기를 희망하신다면, 배포하실 Windows Azure 환경 설정 파일에 실제로 채택할 운영 체제의 버전을 정확히 기술하여 .NET Framework 4.0 RC 버전을 채택한 VM을 기반으로 구동하도록 선택하실 수도 있습니다. 해당 버전은 Windows Azure Geust OS 1.2 중 2010년 3월 1일 버전의 이미지입니다. (http://msdn.microsoft.com/en-us/library/ff436045.aspx)

 

.NET Framework 4.0과 Windows Azure가 결합한다면, 이전보다 더 확장성이 뛰어나고 강력한 클라우드 기반 응용프로그램을 작성할 수 있는 토대가 마련될 것입니다. 여러모로 기대가 많이 되는 소식이고, 새로운 소식이 들어오는대로 정보를 공유할 수 있도록 하겠습니다. 감사합니다. :-)

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

지난번에 올린 Dynamic Programming에서, COM에 대한 Dynamic Binding을 통하여 웹 브라우저를 마치 자바스크립트로 제어하는것과 같은 편리성을 확인할 수 있었습니다. 그리고 여기에 더불어서, Dynamic Programming에 대한 재미있는 내용을 하나 더 다루어보고자 합니다.

 

System.Dynamic 네임스페이스는 닷넷 프레임워크 4.0에서 새로 소개된 네임스페이스로, Dynamic Language Runtime을 활용할 수 있도록 기본 기능들에 대한 사항들을 포함하고 있습니다. 여기서 우리가 알아두면 유용한 리소스 두 가지를 살펴보기로 하겠습니다.

 

1. DynamicObject의 재정의

 

System.Dynamic.DynamicObject 클래스는, System.Dynamic.IDynamicMetaObjectProvider 인터페이스를 구현하는 보통의 클래스입니다. 다만, 생성자가 protected로 보호되어있고, 10종류가 넘는 가상 메서드를 제공하고 있습니다.

 

DynamicObject는 Dynamic Programming에 있어서 필요한 기능들을 거의 모두 내장하고 있습니다. 가령, 컴파일 타임에서 정의되지 않은 멤버를 두고서 단항/이항 연산자를 재정의하거나, 멤버를 가져오거나, 멤버를 설정하거나, 멤버를 삭제하거나, 멤버를 호출하는 등 보편적인 객체 지향 프로그래밍 환경에서 취할 수 있는 액션들을 모두 재정의할 수 있도록 추상화하고 있습니다.

 

여기서 주목할 점은, DynamicObject의 기능을 확장하기 위하여 Expression Parser를 같이 이용한다는 점입니다. 앞 예제에서 보여드린, 마치 JavaScript처럼 코드를 자유자재로 C# 코드를 확장한 예시를 예로 들어본다면, Dynamic 컨텍스트 내에 서술한 C# 코드 조각은 Expression Parser에 의하여 처리되어 Expression 클래스의 인스턴스로 변환됩니다. 이렇게 변환된 객체는 DynamicObject에 미리 정의된 메서드들에 전달되는 것입니다.

 

다음은 Expression 객체를 사용하는 예시 코드입니다. (MSDN에서 발췌함)

 

using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq.Expressions;

// The class derived from DynamicObject.
public class DynamicNumber : DynamicObject
{
    // The inner dictionary to store field names and values.
    Dictionary dictionary
        = new Dictionary();

    // Get the property value.
    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        return dictionary.TryGetValue(binder.Name, out result);
    }

    // Set the property value.
    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        dictionary[binder.Name] = value;
        return true;
    }

    // Perform the binary operation. 
    public override bool TryBinaryOperation(
        BinaryOperationBinder binder, object arg, out object result)
    {
        // The Textual property contains the textual representaion 
        // of two numbers, in addition to the name 
        // of the binary operation.
        string resultTextual =
            dictionary["Textual"].ToString() + " "
            + binder.Operation + " " +
            ((DynamicNumber)arg).dictionary["Textual"].ToString();

        int resultNumeric;

        // Checking what type of operation is being performed.
        switch (binder.Operation)
        {
            // Proccessing mathematical addition (a + b).
            case ExpressionType.Add:
                resultNumeric =
                    (int)dictionary["Numeric"] +  
                    (int)((DynamicNumber)arg).dictionary["Numeric"];
                break;

            // Processing mathematical substraction (a - b).
            case ExpressionType.Subtract:
                resultNumeric =
                    (int)dictionary["Numeric"] - 
                    (int)((DynamicNumber)arg).dictionary["Numeric"];
                break;

            // In case of any other binary operation,
            // print out the type of operation and return false,
            // which means that the language should determine 
            // what to do.
            // (Usually the language just throws an exception.)
            default:
                Console.WriteLine(
                    binder.Operation + 
                    ": This binary operation is not implemented");
                result = null;
                return false;
        }

        dynamic finalResult = new DynamicNumber();
        finalResult.Textual = resultTextual;
        finalResult.Numeric = resultNumeric;
        result = finalResult;
        return true;
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Creating the first dynamic number.
        dynamic firstNumber = new DynamicNumber();

        // Creating properties and setting their values
        // for the first dynamic number.
        // The TrySetMember method is called.
        firstNumber.Textual = "One";
        firstNumber.Numeric = 1;

        // Printing out properties. The TryGetMember method is called.
        Console.WriteLine(
            firstNumber.Textual + " " + firstNumber.Numeric);

        // Creating the second dynamic number.
        dynamic secondNumber = new DynamicNumber();       
        secondNumber.Textual = "Two";
        secondNumber.Numeric = 2;
        Console.WriteLine(
            secondNumber.Textual + " " + secondNumber.Numeric);
       

        dynamic resultNumber = new DynamicNumber();

        // Adding two numbers. The TryBinaryOperation is called.
        resultNumber = firstNumber + secondNumber;

        Console.WriteLine(
            resultNumber.Textual + " " + resultNumber.Numeric);

        // Subtracting two numbers. TryBinaryOperation is called.
        resultNumber = firstNumber - secondNumber;

        Console.WriteLine(
            resultNumber.Textual + " " + resultNumber.Numeric);

        // The following statement produces a run-time exception
        // because the multiplication operation is not implemented.
        // resultNumber = firstNumber * secondNumber;
    }
}

// This code example produces the following output:

// One 1
// Two 2
// One Add Two 3
// One Subtract Two -1

 

Expression 객체를 받아서, 이항 연산을 수행하는 부분을 살펴보면, 언어의 종류에 관계없이 Expression Parser를 이용하여 처리된 구문 분석 결과를 사용한다는 것을 알 수 있습니다. 즉, C#이나 Visual Basic .NET 같은 기본 런타임 언어 뿐만 아니라, IronPython과 같은 언어에도 대응이 가능함을 뜻합니다. 이러한 기능을 활용하여, 메서드의 추가 없이 언어의 특성 만으로 원하는 기능까지 이끌어내는 것이 좀 더 손쉽습니다. 예를 들어, 별도의 메서드 호출 없이 문자열 간 이항 연산 중 더하기 연산에서 HTML에 대응할 수 있도록 <BR /> 태그를 자동으로 덧붙이는 기능을 생각해 볼 수 있을 것입니다.

 

2. Anonymous Type과 ExpandoObject

 

C# 3.0에서는 익명 형식이 도입되었습니다. 이것은 전적으로 LINQ와 같이 동적으로 데이터 형식을 확장해야 하는 시나리오에 최적화된 기술로, LINQ를 위한 새로운 클래스를 작성하는 수고를 덜어주게 됩니다. (Where 절이나 Select절에서 여러 조건을 지정하는 시나리오를 생각하시면 쉽습니다.)

 

그러나 지금 소개하는 ExpandoObject는 어떤 시점에서 임시로 필요한 형식을 개설하는 일과는 별도로, 전형적인 스크립트 언어의 동적 형식을 구현한 것으로, 익명 형식이 컴파일러에 의하여 동적으로 추가되지 않고, 런타임에서 키와 값의 쌍으로 이루어진 Dictionary Type의 객체를 만드는 것이 조금 다릅니다. 이러한 기능 자체는 이미 C# 초기 버전부터 제공되어오던 Hashtable이나 C# 2.0의 Generic 버전의 Dictionary<TKey, TValue> 형식을 이용하는 것과 개념상 유사하지만, 문법적인 관점에서 좀 더 업그레이드 된 형태로 이해할 수 있습니다.

 

아래는 ExpandoObject를 Dynamic Context 아래에서 활용하는 예시입니다.

class Program
{
    static void Main(string[] args)
    {
        dynamic employee, manager;

        employee = new ExpandoObject();
        employee.Name = "John Smith";
        employee.Age = 33;

        manager = new ExpandoObject();
        manager.Name = "Allison Brown";
        manager.Age = 42;
        manager.TeamSize = 10;

        WritePerson(manager);
        WritePerson(employee);
    }
    private static void WritePerson(dynamic person)
    {
        Console.WriteLine("{0} is {1} years old.",
                          person.Name, person.Age);
        // The following statement causes an exception
        // if you pass the employee object.
        // Console.WriteLine("Manages {0} people", person.TeamSize);
    }
}
// This code example produces the following output:
// John Smith is 33 years old.
// Allison Brown is 42 years old.

 

그리고 아래의 코드는 Dictionary의 경우와 마찬가지로, ExpandoObject의 모든 멤버들을 Reflection 없이 나열하는 것입니다. (내부적으로 Dictionary와 같은 개체를 사용하여 멤버들을 관리하고 있으므로 Reflection을 이용하지 않는것으로도 볼 수 있습니다.)

dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;

foreach (var property in (IDictionary)employee)
{
    Console.WriteLine(property.Key + ": " + property.Value);
}
// This code example produces the following output:
// Name: John Smith
// Age: 33

 

ExpandoObject는 문법적으로 Dictionary 컬렉션을 확장한 것으로 이해할 수 있기 때문에, 확정적이지 않은, 변동 가능성이 있는 다수의 매개 변수를 복잡하지 않게, 문법적으로 융합된 형태로 코드를 작성하기 수월하게 합니다. Dictionary 컬렉션 개체를 생성하고 넘기는 동작을 미화한 것으로 볼 수 있을 것입니다.

 

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

Visual Studio 2010 베타 2가 이 글을 쓰는 현 시점에 Express Edition과 함께 새롭게 공개되었습니다. .NET Framework 4.0과 더불어서 C# 4.0, Visual Basic .NET 10.0 등 언어들의 기능도 새롭게 향상되었으며, 특히 이목을 끄는 것은 Dynamic Language Runtime과 연동되는 Dynamic Programming에 관한 것입니다.

 

Dynamic Programming에 대해서, 철수네 소프트웨어 세상 블로그 (http://blogs.msdn.com/bkchung/)에 소개된 내용을 오래 전에 처음 포스팅을 했었지만 최근까지도 dynamic 키워드의 실용적인 사례를 찾지 못하고 있었습니다만, 최근 dynamic 키워드의 새로운 활용 가능성을 새롭게 발견하였습니다. 여러 시나리오가 있을 수 있겠지만 제가 오늘 이 포스트를 통해서 조명해보고자 하는 것은 Windows Forms가 제공하는 Web Browser와의 연동에 관한 것입니다.

 

Windows Forms가 버전 2.0에 들어서면서부터 매우 실용적인 컴포넌트를 새롭게 추가하였는데 바로 웹 브라우저 컨트롤이 그것이었습니다. 웹 브라우저 컨트롤은 단순히 브라우저로서도 활용할 수 있지만 잘 활용한다면 사용자 인터페이스를 웹 기반으로 업그레이드하는 것 또한 가능합니다.

 

하지만 COM Interop 프로그래밍에 기댈 수 밖에 없는 부분은 여전히 많았고, 당시의 C# 언어 사양만으로 COM Interop을 다루는데에는 비효율적이고 생산성이 떨어지는 부분이 많았습니다. 그런 이유로, 예전의 브라우저 컨트롤보다는 "조금 뛰어난" 수준으로 인지되는데에 그쳤습니다. 하지만 이번에 새로 소개되는 Dynamic Programming과 결합하면 매우 매력적인 프레임워크로 다시 거듭나게 됩니다.

 

Dynamic Programming을 시험해볼 좋은 자바스크립트 예제를 찾던 중, http://www.javascriptfreecode.com/34.htm 의 소스 코드를 발췌하여 Dynamic Programming 버전으로 만들어보았습니다.

 

본디 이 스크립트가 하는 일은 Internet Explorer가 고유하게 제공하는 웨이브 필터를 활용해서 텍스트를 화려하게 보일 수 있도록 치장하는 것입니다. 그러나 이 기능을, 여러 브라우저가 보는 페이지로서가 아닌, 온전히 Windows Forms 응용프로그램만을 위한 고유한 기능으로 바꾸어보도록 하겠습니다.

 

  1. 폼에 웹 브라우저 컨트롤을 새로 추가합니다.
  2. 웹 브라우저 컨트롤이 처음 보일 페이지를 about:blank 로 설정합니다. 빈 문서를 준비시키도록 하는데에 도움이 됩니다.
  3. 기본 이벤트인 DocumentCompleted 이벤트 핸들러를 새로 추가합니다.
  4. 아래의 코드를 작성합니다.

private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    dynamic document = this.webBrowser.Document.DomDocument;
    dynamic window = this.webBrowser.Document.Window.DomWindow;

    document.write(String.Format(@"
<!-- Original Source: http://www.javascriptfreecode.com/34.htm -->
<div id=""Zittertext"" style=""font-weight: bold; font-size: 25pt; filter: Wave(freq=5, light=0, phase=8, strength=1); width: 100%; color: orange;"">
<div style=""background-color: #FFFF00; text-align: center; color: black; display: inline;"">
{0}
</div>
</div>
", window.prompt("Please type a message to display: ", "Hello World!")));

    Action DynWave = () =>
    {
        dynamic filter = document.getElementById("Zittertext").filters[0];
        if (filter.freq > 130)
            filter.freq = 15;
        filter.freq++;
        if (filter.phase > 50)
            filter.phase = 1;
        filter.phase++;
        if (filter.strength > 1)
            filter.strength = .1;
        filter.strength++;
    };

    Timer timer = new Timer();
    timer.Tick += (a, b) => DynWave();
    timer.Interval = 50;
    timer.Enabled = true;
}

 

위의 코드에서 우리가 관심있게 봐두어야 할 부분은 dynamic으로 선언한 변수 뒤에 나타나는 표현식들입니다. 컴파일러 기반의 언어들은 늘 그렇듯 문법의 정확성을 언제나 따지게 됩니다. C#도 분명히 그런 언어였습니다. 하지만 Dynamic Programming을 통하여 위와 같이 컴파일 시점에는 존재하지 않는 내용을 런타임 때에 유추해낼 수 있게 되었습니다.

 

여기서 의문점이 드는 것이 있는데, 그렇다면 이를 유추해내기 위해서 어떤 식으로 구현을 제공하는가에 대한 부분입니다. 이 부분에 대한 답은 바로 .NET Framework가 런타임 과정에서 정확한 객체 정보를 확인하기 위해서 사용하는 ObjectBinder에 있습니다. regasm 유틸리티로 등록해두었던 COM Interop Assembly나 Primary Interop Assembly에 대한 내용을 런타임 차원에서 관리하고, 이를 자동으로 연결하고 있는 것입니다. 직접 프로젝트에서 참조를 하지 않았다고 할지라도 그러합니다.

 

그리고 이러한 기능 위에 DLR과 더불어서 이미 LINQ에서 소개된 적이 있는 Expression Tree 해석 엔진에 의하여 C# 기준으로 작성된 코드를 Object Binder가 가지고 있는 정보와 일치시켜 정확한 기능을 하는 실제 코드를 컴파일 과정에서 작성하게 되는 것입니다. 이것은 형식 정보를 읽어서 매번 같은 컬렉션을 여러번 반복하면서 조회하는 Reflection 기반의 프로그래밍보다 훨씬 빠르게 동작하고, 훨씬 정확도가 높습니다.

 

위의 코드를 실행한 결과는 아래와 같습니다. 중간에 어떤 메시지를 표시할 것인지를 묻는 브라우저의 프롬프트 창에 원하는 메시지를 넣어보는 것도 괜찮을 것입니다.

 

 

Dynamic Programming에 대한 자세한 내용은 http://msdn.microsoft.com/en-us/library/dd264736(VS.100).aspx 의 내용을 참고하시면 도움이 될 것입니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

Microsoft .NET이 처음 소개되어 전세계적으로 널리 사용되어지기 시작한지 어느덧 10년에 가까워져 가고 있습니다. 차세대 .NET 기술이 일정한 주기마다 한번씩 새롭게 리뉴얼이 되고 발표되고 있습니다만 이번에는 다른 때보다 더욱 특별한 의미를 가지게 되는 것 같습니다.

 

금번 국내에서 열리는 Microsoft Techday 행사는 Windows 7, Windows Server 2008 R2를 중심으로, 조만간 발표될 .NET Framework 4.0, Visual Studio 2010, Exchange Server 2010, Expression Series 3와 같은 새로운 제품과 기술들을 살펴볼 수 있음은 물론, Microsoft가 생각하는, .NET 기술을 통한 차세대 컴퓨팅 기술의 전망이 무엇인지를 잘 보여주는 그런 행사가 될 것입니다.

 

Techday 행사는 크게 두 트랙으로 구분되며, 개발자들을 위한 트랙과 IT 전문가들을 위한 트랙으로 구성되어있습니다. 전체 행사는 온라인 세미나의 형태로 진행이 되며, 국내에서 활동하시는 MVP 분들과 에반젤리스트 분들의 세션을 들으실 수 있습니다. 그리고 개인적으로는 키노트의 내용이 상당히 흥미로운 점이 많은것 같습니다. :-)

 

다음의 URL을 통하여 Agenda를 살펴보고 여러분께서 원하시는 세션을 선택하시면 됩니다.

 

http://techdays.co.kr/Sessions/

 

최신 트렌드나 기술에 대해서 정보를 빠르고 정확하게 구할 수 있는 자리는 그렇게 흔하지 않을 것입니다. 이번 Techday 행사를 통하여 Microsoft의 기술 비전을 공유하고, 체험할 수 있는 기회를 꼭 마련하시기 바랍니다.


 

컴퓨팅 플랫폼의 획기적인 변화는 기업의 데이터 센터에서 우리 가정의 PC와 웹 브라우저,
그리고 내 손 안의 디바이스 단말까지 모든 일상을 바꾸고 있습니다. 또한 불확실한 미래와 비용 절감의 압박은
비즈니스에서 IT의 역할을 더욱 강화시키고 있습니다.

마이크로소프트는 10월 말 출시 예정인 새로운 운영 체제 Windows 7을 비롯하여
Visual Studio 2010, Expression 3, Windows Server 2008 R2, Exchange 2010을 비롯한 다양하고 우수한 기술로
개발자와 IT 전문가들의 새로운 시대를 열어드리고자 합니다.

클라이언트부터 웹, 모바일, 서버 그리고 클라우드까지 최신 플랫폼과 기술 트렌드를 한 자리에서 만나볼 수 있는
국내 최대 온라인 컨퍼런스 TechDays 2009에서 주요 기술 흐름을 점검하시기 바랍니다.

감사합니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

C#을 제 포트폴리오상의 주력 프로그래밍 언어로 삼은지 벌써 수 년이 지났고 어느덧 C#의 네 번째 버전이 베일을 벗고 있습니다. C#을 처음 접할 때만 하더라도 Cava 라는 웃지 못할 별명 (C + Java)이 꼬리표처럼 따라 다녔지만 이제는 C#은 Java와 다르다는 것을 증명해 나가고 있고 C# 3.0 이후로는 더 이상 Cava라는 이름이 따라다니는 불행이 없다는 것이 참 좋았습니다. :-)

이번 C# 4.0에서는, 제가 이전에 C# 3.0에서 우려했던 var 키워드의 모습을 실제로 구현하는 dynamic 키워드가 등장합니다. var 키워드가 컴파일 타임에서의 유추에 의존하는 것이면 dynamic 키워드는 예전의 Variant 키워드를 연상하게 하는 내용입니다. 하지만 예전에 스크립트 프로그래밍을 구현하던 때와는 중요한 차이점이 있는데, 바로 Reflection의 유무입니다.

Reflection이 없었을 때의 Duck Typing은 사치의 절정이었습니다. 메모리 소모량도 크고 불안정하기까지 했으니까요. 하지만 .NET Framework가 제시하는 Duck Typing은 개념이 많이 다른데, 그 기반에는 Reflection과 DLR (Dynamic Language Runtime)이 저변에 있습니다.

DLR은 이미 Iron 시리즈 (IronPython, IronRuby 등)에서 핵심 엔진으로 채택하여 사용 중인 Microsoft의 스크립트 언어용 런타임입니다. C# 4.0은 DLR에 대한 호환성을 높일 목적으로 dynamic 키워드를 이들 스크립트 언어에서 사용하는 것과 같은 의도로 사용할 수 있게 해줍니다. 다음의 예를 보기로 하겠습니다.

dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);

단정을 하고 본다면 위의 코드에서 calc는 object 형식과 다르지 않으며, 컴파일러 수준에서 Reflection으로 Add 메서드를 찾아내고 동적 파라미터로 10과 20을 배열로 구성하여 호출한 결과를 다시 가져온 것입니다. 하지만 언어의 확장과 DLR이 미리 제공하는 인터페이스인 IDynamicObject 인터페이스를 구현하여 목적에 맞고 좀 더 빠르게 동작하도록 확장할 수 있습니다.

object calc = GetCalculator();
Type calcType = calc.GetType();
object res = calcType.InvokeMember("Add", BindingFlags.InvokeMethod, null, new object[] { 10, 20 });
int sum = Convert.ToInt32(res);

특히 주목해야 할 것은 IDynamicObject 인터페이스를 이용하여 기존의 COM Interop 프로그래밍은 형 변환 작업 없이, 오버헤드 없이 손쉽게 프로그래밍을 할 수 있게 됩니다. C# 이야기는 아니지만 이러한 수혜를 바탕으로 Visual Basic .NET의 차기 버전도 더욱 향상된 Lazy-Binding 프로그래밍 기술을 가지게 될 것으로 봅니다.

요약하면, 이번 C# 4.0은 동적 프로그래밍 언어로서의 면모를 갖추는 본격적인 단계로 정의내릴 수 있습니다. 다음 Article에서는 C# 4.0이 가지는 또 다른 파격적인 변화 하나를 소개하겠습니다.

참고: http://blogs.msdn.com/bkchung/archive/2008/11/09/c-4-0-2008-10-ctp.aspx

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)