By 셸리 파워스, Developing ASP Components, 2nd Edition의 저자
관련 기사: ASP.Net 환경 안에서 COM/COM+ 객체 이용하기
"C#을 어떻게 발음하는지 아세요?"
"그 언어는 예전에 Java라고 했었죠."라는 농담이 있다. 이와 유사하게, .NET은 "이전에 COM/DCOM이라고 알려졌던 인프라스트럭쳐(infrastructure)"라고 말할 수 있다.
.NET의 구조는 COM/COM+와 분명히 다르다. 그러나 .NET에 대한 정보가 충분하지 못해서 대부분의 사람들은 무엇이 다른지 궁금해 하는 단계에 머물러 있다. 여러분은 회사에서 .NET의 프로덕션 릴리스(release)를 적용하려고 했을 때, .NET을 도입하면서도 기존에 개발한 컴포넌트를 계속해서 지원하고, 생성할 수 있는 방법을 알고 싶어할 것이다. 특히, 비주얼 베이직에서 작성한 COM+ 컴포넌트와 ASP로 작업한다면, 그러한 컴포넌트를 새로운 .NET 환경으로 마이그레이션(migration) 하는 방법에 관심이 있을 것이다. 이 글에서는 현재 VB로 개발한 ASP 컴포넌트가 .NET에서 어떻게 이용되는지와, .NET에서 바뀐 점에 대해 알아볼 것이다. 특히, 기존의 컴포넌트가 앞으로 .NET과 호환되도록 하는 것에 대해 알아 볼 것이다.
가변형은 무엇인가?
COM/COM+와 .NET에서 가장 중요한 차이는 가변형이 없어진 것이다. 가변형의 기능은 객체형(object data type)을 받아들일 수 있다는 것이다. 특히, 컴포넌트를 개발하면서, 컴포넌트의 메소드로 데이터를 주고 받는데 가변형을 사용했던 비주얼 베이직 프로그래머에게는 이것이 가장 큰 변화다.
역주 : 비주얼 베이직 6.0에서 Variant형은 고정 길이 문자열을 제외한 모든 유형의 데이터를 포함할 수 있는 범용 데이터 형식이다. .NET의 기반인 CLR(Common Language Runtime) 환경에서 범용 데이터 형식으로 Object를 사용한다.
호환성을 위해서, 새로운 컴포넌트를 작성할 때 가변형 대신에 데이터 형을 지정해야 한다. 그러나 기존의 코드에서 가변형을 사용했다면, 마이크로소프트는 가변형을 포함한 컴포넌트를 .NET으로 포팅할 수 있는 두 가지 방법을 제공한다.
첫 번째는 비주얼 스튜디오 .NET에서 이전 비주얼 베이직 코드를 열 때, 자동으로 수행되는 비주얼 스튜디오 업그레이드 마법사를 사용하는 것이다. 이 마법사는 모든 인스턴스(instance)의 가변형(Variant)을 객체형(Object)으로 변환한다. 가변형 키워드를 사용하려고 하거나, 입력하려고 하면, 자동으로 객체형으로 바뀐다. 따라서 추가로 작업을 할 필요가 없다.
예를 들어, 다음과 같은 서브루틴이 있다면:
Sub test (ByVal varValue As Variant)
|
업그레이드 마법사는 서브 루틴을 다음과 같이 변경한다:
Sub test (ByVal varValue as Object)
|
비주얼 베이직 6.0에서 가변형(variant)에 대한 기본 데이터 형을 제공하지 않는다면, VB.Net에서 업그레이드 마법사는 자동으로 변수를 객체형(Object)으로 재정의한다(업그레이드 마법사는 다른 업그레이드 사항들도 수행하는데, 이 점에 대해서는 기사 전체에서 자세히 다룰 것이다).
.NET 환경과의 호환성을 위해서 컴파일된 컴포넌트를 열어보거나 변환하지 않아도 된다. 컴포넌트를 .NET으로 포팅하는 두 번째 방법은 TlbImp 유틸리티를 사용하는 것이다. 이 유틸리티를 사용하는 방법과 설명은
지난 기사에 소개했다. 기본적으로 이 유틸리티는 컴포넌트를 재컴파일하지 않고, .NET의 관리형 코드 환경에서 실행되도록 .NET 어셈블리를 작성한다.
역주 : .NET 환경에서는 컴포넌트라는 용어를 쓰지 않고, 어셈블리라는 용어를 사용한다.
가변형이 없어진 것이 VB 6.0과 .NET의 유일한 변화는 아니다. 여기서 다루는 비주얼 베이직 데이터 형과 형 검사 또한 중요한 변화 중의 하나다.
데이터 형과 데이터 타이핑(Data Type and Data Typing)
과거에 비주얼 베이직의 주요한 문제는(특히, C++나 Java 프로그래머들) 엄격한 데이터 형 기반 언어가 아니라는 점이다. 다음 예제처럼, 비주얼 베이직 6.0에서 숫자와 문자열을 연결하면 비주얼 베이직은 자동으로 숫자를 문자열 값으로 변환한다(이러한 변환을 암시적 변환이라고 한다).
iValue = 123
StrSum = iValue & "123"
|
이러한 종류의 연산은 위에서 보인 중첩 연결 연산자("&")를 사용할 때 여전히 .NET에서 허용된다. 그러나 문자열이 있어야 할 곳에 숫자 값을 사용하는 경우에는 에러가 발생할 것이다. 예제처럼, 숫자 값이 문자열로 처리될 수 없으므로, 비주얼 베이직은 숫자 값을 문자열로 자동으로 변환 할 것이다.
Sub tstValue (String strValue As String)
...
Dim iValue As Integer
iValue = 13
tstValue iValue
|
위 예제는 비주얼 베이직 6.0에서는 잘 동작하지만 VB.Net에서는 동작하지 않는다. 더 강력한 데이터 형 정의를 지원하기 위해, 비주얼 베이직 .Net에서는 Option Strict 문을 사용한다.
이전 버전의 Option Explicit과 유사한 Option Strict문은 명시적인 변수 선언을 하도록 한다.
그러나 Option Strict는 수치형 등을 무작위로 변환하는 것을 제한할 뿐만 아니라 문자열과 숫자형 사이에 암시적 변환 등을 제한하여, 데이터 보호 능력을 강화한다. 무작위 변환이란, integer형을 double형으로 변환하는 것과 같이 수치나 데이터가 더 크거나 더 작은 데이터형으로 변환하는 것 등을 말한다.
Option Strict는 또한 후기 바인딩을 못하게 한다. Option Strict를 사용하면, 다음과 같이 비주얼 베이직 6.0에서 잘 되는 것이 .NET에서는 컴파일 에러를 발생한다:
Dim obj As Object
...
obj.SomeMethodCall ...
|
후기 바인딩은 분산/웹 기반 환경 등에서 응용 프로그램 컴포넌트 사이의 유선 기반의 통신에 있어 좋지 않다. 따라서 비주얼 베이직 6.0 컴포넌트를 개발할 때에는 후기 바인딩(late-binding)의 사용을 피해야 한다.
후기 바인딩은 항상 실제 코드에서 모든 호출에 대해 두 개의 메소드를 호출해야 한다. 하나는 메소드에 관한 정보를 찾는 것이며, 또 하나는 메소드 자체를 질의하는 호출이다. 코드의 처음에 Option Strict를 둠으로써, 여러분의 코드에 우연히라도 후기 바인딩 코드를 남겨놓지 않을 수 있다.
많은 비주얼 베이직 응용 프로그램과 마찬가지로 느슨한 변환 형이 제공되고 있지만, 이러한 새로운 기능들 때문에 비주얼 베이직 .NET은 더 강력한 형 기반 언어가 될 수 있다. 이러한 점은 비주얼 베이직 자체와 .NET의 일부분으로 포함될 비주얼 베이직 사이에 꼭 필요한 절충 요소이다.
작성한 코드를 보다 강력한 형 기반의 환경으로 옮기도록 하려면, 현재 작업중인 응용 프로그램에 반드시 변수 선언을 하도록 Option Explicit 문을 사용해야 한다. 또한, 보다 큰 정밀도나 크기의 숫자를 보다 작은 데이터 형으로 변환하는 것과 같은 데이터 손실 가능성이 있는 변환 코드는 제거한다. 수치형과 문자열을 같이 사용할 경우에 명시적인 형 변환 함수를 사용한다:
StrSum = "Account is " & CStr(iValue) & " overdue"
|
그리고 앞으로의 호환성 뿐만 아니라, 현재 여러분이 작성하고 있는 비주얼 베이직 응용 프로그램의 퍼포먼스를 향상시키기 위해 타입 라이브러리를 이용하여 초기 바인딩을 수행한다.
기존의 비주얼 베이직 6.0 프로젝트를 비주얼 베이직 .NET에서 열 때, 업그레이드 마법사는 이전 호환성을 위해 자동으로 Option Strict 문에 Off를 붙이며, Option Explicit 문도 그대로 남아있다(기본값은 "off"이다).
역주 : Option Explicit 선언이 없는 비주얼 베이직 6.0 프로젝트를 비주얼 베이직 .NET으로 변환하면 업그레이드 마법사는 이전 호환성을 위해 Option Strict Off 문장을 추가한다. Option Explicit 선언이 있는 프로젝트를 비주얼 베이직 .NET으로 변환할 경우에 업그레이드 마법사는 Option Strict Off문과 Option Explicit On 문을 추가한다. 완전한 형 기반의 방법으로 포팅하려면 변환 후에 Option Explicit On 문을 삭제하고, Option Strict On 문을 사용한다.
비주얼 베이직에서 .NET으로 변화한 또 한가지 점은 (특히 컴포넌트 개발자들에게 중요한) 다음 절에서 다룰 정수형(integer)의 크기이다.
정수형 크기
비주얼 베이직과 비주얼 베이직 .NET 사이의 중요한 데이터 형의 변화는 정수형(integer)의 크기이다. 비주얼 베이직.NET에서 정수형은 .NET의 System.Int32 데이터 형과 같으며, 32비트 길이를 가지며, 부호형(signed)이다. 32 비트 정수형의 장점은 윈도우 2000과 같은 32 비트 운영 체계에서 16비트 정수 연산보다 더 빠르다는 것이다.
정수형 크기가 바뀜으로서 얻을 수 있는 다른 이점은 C++, Java, Perl과 같은 주류 언어들과 동일 선상에 있게 된다는 것이다. 여러분이 컴포넌트 개발을 하고 있고, 특히 다른 언어에 기반한 컴포넌트로 작업을 한다면, 다른 대부분의 언어가 32비트 정수형을 사용할 때 비주얼 베이직은 16비트 정수형을 사용한다는 것이다. 이러한 점은 펄 스크립트에서 비주얼 베이직 컴포넌트를 사용하려고 할 때 잘 나타난다.
16비트 수치형을 계속 이용하기를 원하면, 새로운 데이터 형인 Short를 이용하면 된다. 64비트 값은 Long 형을 사용한다.
업그레이드 마법사는 integer형을 16 비트인 short형으로 변환함으로써 비주얼 베이직 응용 프로그램의 정수를 유지한다. 여러분의 컴포넌트가 새로운 .NET 정수형으로 변환하고 싶다면, 비주얼 베이직 6.0에서 개발할 때 변수와 메소드 인자에 Long형을 사용한다.
역주 : 비주얼 베이직 .NET에서 기본 정수형의 크기로 32비트 정수를 사용하지만, Len 함수등은 여전히 16비트 정수를 반환하므로 실제 포팅시에 CShort등의 변환 함수를 빈번히 사용해야 한다. 아직까지는 전체적으로 통일되어 있지 않다.
또 다른 데이터 형의 변화는 더 이상 currency 형을 지원하지 않는다는 것이다. 대신에 새로운 Decimal 타입이 더욱 정교한 자료형을 제공한다.
비주얼 베이직 6.0에서, Decimal 데이터 형은 Variant형의 서브 타입(sub-type)으로만 이용할 수 있었다.
날짜형 또한 비주얼 베이직 .Net에서 다르게 다루어진다. 현재의 Double 형식 대신에 .Net의 DateTime 포맷으로 구현된다. 이전과 새로운 데이터 형식 사이를 변환하기 위해, 마이크로소프트는 이전 Double 형 값을 새로운 데이터 형으로 변환할 수 있는 ToDouble과 같은 루틴을 제공하고 있다.
역주 : 비주얼 베이직의 Date 형은 내부적으로 Double 형을 사용하며, 비주얼 베이직 .Net은 내부적으로 64비트 정수형으로 처리한다. 비주얼 베이직의 Double형은 32비트 정수이며 비주얼 베이직 .Net에서는 Integer로 변환된다. 따라서 날짜형식은 이전 버전과의 호환성을 위해서 ToDouble, ToOADate, FromOADate등의 변환 함수를 사용한다. 비주얼 베이직 .Net의 Date형은 CLR의 System.DateTime 데이터 형과 같다.
코드를 가능한 한 수작업으로 마이그레이션 하지 않으려면 기존의 코드를 새로운 데이터 형으로 변환하기 위해 컴포넌트에서 Date형과 Currency형의 사용을 분리해야 한다.
함수 파라미터에 있어서 비주얼 베이직 .Net에서의 다른 중요한 변화는 서브루틴의 구조의 변경과, 인자를 넘기는 방법의 변화이다.
서브루틴의 변화
비주얼 베이직 6.0과 비주얼 베이직 .NET 사이에 호출되는 프로그램에서 인자를 넘기는 방법이 다르다. 비주얼 베이직 6.0에서는 기본적으로 모든 인자는 ByVal 키워드가 사용되지 않으면 참조에 의해(by reference) 값을 전달 한다. 이것은 프로시저(procedure)가 호출하는 프로그램이 인자를 넘기는 데 사용한 변수를 수정할 수 있도록 하며, 종종 이것은 예상하지 못한 결과를 일으킨다.
예제를 보자
Sub testValue(iNewValue As Integer)
iNewValue = iNewValue + 20
End Sub
...
Dim iValue As Integer
iValue = 2
Call testValue(iValue)
" value is now 22 rather than 2
|
비주얼 베이직 .Net에서는 데이터가 우연히 변경되는 것을 막기 위해, 기본적으로 값에 의해(By Value) 인자가 전달된다. 참조에 의해 인자를 전달하려면 명시적으로 ByRef 키워드를 사용해야 한다.
호환성을 위해 비주얼 베이직 6.0 코드의 모든 인자에 ByVal, ByRef 키워드를 명시적으로 사용해야 한다.
Optional 인자 또한 비주얼 베이직 .Net에서 다르다. 6.0에서는 기본 값이 없이도 Optional 키워드를 사용할 수 있었다.
Sub someRoutine (Optional ByVal iValue As Integer)
|
6.0에서는 값이 변했는지 검사하기 위해 IsMissing을 사용했다. 비주얼 베이직 .Net에서는 Optional 인자에 대해서 기본 값을 반드시 사용해야 한다.
Sub someRoutine (Optional ByVal iValue as Integer = 0)
|
코드에 Optional 키워드를 사용하고 있다면 .NET으로 손쉽게 변환하기 위해 기본 값을 명시하는 것이 좋다. 이것은 코드를 .NET으로 변환하기 쉽게 할 뿐만 아니라, 오늘날 적용되는 좋은 프로그래밍 습관이기도 하다. - IsMissing을 사용하는 것은 프로시저를 불필요하게 복잡하게 만드는 것이다.
비주얼 베이직 .NET에서의 다른 변화는 배열(array)과 같은 구조화된 데이터이다.
배열의 구조적 변화
배열을 사용한다면, 비주얼 베이직 .NET에서 Option Base문을 사용하여 시작값을 재정의할 필요가 없다.
대부분의 프로그래밍 언어들처럼 이제 모든 배열은 0에서부터 시작한다. 다시 말하자면, 이러한 변화는 프로그래밍 언어의 상호 운용성을 위해서 필요한 것이다(.NET에서 고무할만한 것이다). 게다가, 6.0에서 했던 것처럼 .NET에서 고정된 배열 사이즈를 정의할 수는 없다.
Dim strValue(10) as String
|
위와 같은 선언을 하는 대신 다음과 같이 선언해야 한다.
Dim iValue as Integer = new Integer(10) { }
|
이것은 10개의 지정된 데이터 형을 저장할 수 있는 공간을 할당하지만, 그 자체로는 배열의 크기를 고정할 수 없다. 배열은 ReDim문을 사용해서 변경할 수 있다.
코드가 최대한 호환성이 있도록 하려면 Option Base 문을 사용하여 배열을 초기화하지 말아야 한다. 이러한 선언을 사용하지 말고, 배열이 0부터 시작하지 않도록 한다. 업그레이드 마법사는 프로젝트를 처음 열 때, 0부터 시작하도록 배열을 변환하다. 마이크로소프트는 데이터 형의 변화나 구조적인 비주얼 베이직의 변화를 제한하지 않는다. .NET에서는 내장 함수도 바뀌었다.
내장 함수와 네임 스페이스
이 기사에서 언급하고 싶은 비주얼 베이직 .NET에서의 새로운 큰 특징은 네임 스페이스 개념이다. 네임 스페이스는 비주얼 베이직 6.0의 타입 라이브러리에 대한 레퍼런스를 붙이거나, C++에서 타입 라이브러리를 임포트하는 것과 비슷하게, 응용 프로그램에게 생성된 컴포넌트를 외부로 노출시키는 방법이다.
비주얼 베이직 .NET에서 다음과 같은 선언으로 네임 스페이스를 임포트할 수 있다.
imports Microsoft.VisualBasic.ControlChars
|
임포트를 사용하여, 네임 스페이스 이름을 지정하지 않고 네임 스페이스의 멤버를 참조할 수 있다.
dValue = Math.sqrt(number)
|
위 코드를 다음과 같이 쓸 수 있다.
비주얼 베이직 ASP 컴포넌트의 호환성에 관한 기사에서 네임 스페이스 개념에 대해 소개를 하는 이유는 많은 비주얼 베이직 6.0 내장 함수들이 System.Math와 같은 네임 스페이스 안에 정의되어 있기 때문이다.
네임스페이스 사용에 기반한 코드에서 중요한 변화는 String 데이터 형이다. 이제 코드에서 String 형에 직접 접근할 수 있다.
비주얼 베이직 .NET에서 String은 실제로 System.String 네임 스페이스에 정의되어 있다. 사실, 비주얼 베이직의 내장 함수들이 네임 스페이스에 정의되어 있는 것처럼, 모든 데이터 형도 System 네임 스페이스에 정의되어 있다.
이전 버전과 호환성 있게 하기 위해, 마이크로소프트는 기존의 비주얼 베이직 6.0 컴포넌트를 임포트할 수 있도록 Microsoft.VisualBasic.Compatibility.VB6와 같은 네임 스페이스를 제공한다. 이것을 통해 실질적인 수정을 할 때까지 비주얼 베이직 .NET 환경에서 응용 프로그램이 잘 동작할 것이다.
마지막으로 비주얼 베이직 .NET에서 변화한 점은, 새로운 환경에서의 프라퍼티(Properties)의 효과와 Set문과 Let문을 사용한다는 것이다.
프라퍼티(property)의 변화
비주얼 베이직 6.0에서 스칼라 값을 할당할 때에는 직접 할당을 사용하고, 변수에 객체를 할당할 때에는 Set 키워드를 사용해야만 한다.
비주얼 베이직 .NET에서 프라퍼티를 지원하는 구조가 변경되었다. 프로그래밍 언어에서 Set, Get 키워드는 이제 허용되지 않는다.
이전에 ADO로 작업을 할 때, 연결 객체를 할당하기 위해 다음과 같은 문맥을 사용했던 경우를 예로 들 수 있다.
Set rs.ActiveConnection = conn
|
Set 키워드를 사용하지 않아도, 연결 객체의 기본 속성(객체 그 자체가 아니라 연결 문자열 속성)에 할당된다.
rs.ActiveConnection = conn
|
위와 같이, 코드는 여전히 잘 동작한다. 데이터베이스 연결은 ResultSet 객체에 할당된다. 그러나 현재 연결 객체를 사용하는 대신 연결 문자열을 사용하여 두 번째 연결이 생성된다.비주얼 베이직 .NET은 인자(parameter)를 갖지 않는 한, 더 이상 기본 속성을 지원하지 않는다. 이는 사람들이 요청해 왔던 디자인 변화 중 하나이며, 오랫동안 지연되어 왔던 것이기도 하다.
이러한 형의 변화와 함께, ADO 연결 객체에서 보여준 것처럼 기본 속성의 얘기치 않은 할당은 더 이상 일어나지 않는다. 이 점은 언어와 도구에서 명확하게 향상된 부분이다.그리고 .NET 구조는 속성 값을 설정하고 가져오기 위한 방법을 제공하기 위해 속성을 새로운 방법으로 정의하였다. 비주얼 베이직 .NET의 PDC-Based 릴리스에 있는 속성에 대한 예제는 다음과 같다.
" Internal storage, always in degrees.
Dim Degrees As Double = 0
Property Angle(ByVal Radians As Boolean) As Double
Get
Angle = Degrees
If Radians Then Angle = Angle * 3.1415926536 / 180
End Get
Set
" The keyword Value stands for the value passed in.
Degrees = Value
If Radians Then Degrees = Degrees * 180 / 3.1415926536
End Set
End Property
|
속성을 설정하고 가져오기 위한 방법으로 Property Let, Property Set, Property Get 구문은 더 이상 필요하지 않으며, 언어 지원에서 제거되었다. 즉, 이 기사에서 다룬 많은 변화처럼, 업그레이드 마법사는 비주얼 베이직 6.0 프로젝트를 열 때, Set, Get, Property 의 사용을 자동으로 수정할 것이다. 컴파일되었으며, TlbImp에 의해 래핑된 컴포넌트들은 이러한 코드 내부 변화에 영향을 받지 않는다.
요약
아직까지 비주얼 베이직 .NET에서 바뀐 점들을 모두 알아본 것은 아니며, 비주얼 베이직.NET에는 여전히 수정되어야 할 사항들이 있다. 그러나 이 글을 읽으면 앞으로 변화할 방향을 감지할 수 있기 때문에 현재 있는 VB 컴포넌트나 컴포넌트 개발에 어떤 영향을 미칠 지 잘 이해할 수 있을 것이다.
중요한 부분들이 바뀌었지만, 다행히 변화가 그렇게 심한 것은 아니다. 사실 비주얼 베이직 컴포넌트를 새로운 .NET 아키텍처로 쉽게 마이그레이션 할 수 있는 방법이 많이 있다.마이크로소프트는 비주얼 베이직 6.0의 기능을 복원할 것이고, 비주얼 베이직 .NET의 첫번째 베타를 내놓았고, 비주얼 베이직 6.0의 몇몇 기능들을 살릴 것이라고 발표했다. 이러한 움직임은 비주얼 베이직 .NET이 VB.NET 의 정식 발표 이전에 개발된 응용 프로그램을 지원할 것이라는 것이다.
하지만 새로운 응용 프로그램이나 컴포넌트를 작성한다면, 예전의 비주얼 베이직 코드 기반에 의존하기 보다는 비주얼 베이직 .NET과 호환될 수 있도록 코드를 수정하는 것이 좋다.
셸리 파워스(Shelley Powers)는 자신의 회사인 Burning Bird Enterprises의 컨설턴트로 일하고 있다. 지난 몇 년동안 여러 플랫폼과 툴을 이용하여 다양한 분산/웹 어플리케이션을 개발하였으며, Developing ASP Components, 2nd Edition외에 ASP, P2P, C#, WAP, Dynamic HTML, Java Script, Java/J2EE, CGI, Perl, 일반 웹 기술에 대한 서적을 저술 또는 공동저술 하였다.