login register Sysop! about ME  
qrcode
    최초 작성일 :    2001년 05월 17일
  최종 수정일 :    2001년 08월 08일
  작성자 :    LikeJazz (박상길)
  편집자 :    LikeJazz (박상길)
  읽음수 :    51,626

강좌 목록으로 돌아가기

필자의 잡담~

LikeJazz님... 이 분은 태오를 상당히 냉정하게 비판하시는 분입니다... Wowbook 서평을 통해서 이분을 알게되었지요. 어렵사리 제공해 주신 COM+ 관련 강좌. 그래서인지 더욱 소중하게 느껴지는 외부강좌입니다.

LikeJazz (likejazz@korea.com)

태요님의 게시판 강좌에 발맞춰 COM+ 구현방법을 실제 게시판 적용사례와 함께 강의해보고자 한다. 우선 이 글은 asp 중급개발자 이상을 타겟으로 하며 게시판 리스트페이지를 예제로 하여 COM+ 컴포넌트를 구현해보도록 하겠다. 약간의 객체지향방법론(UML), VB 로 COM+ 구현에 대한 이론적인설명이 곁들여질 예정이다. 물론 상세한 자료는 이미 MSDN 과 Wrox 사의 책들로 많이 공개되어있으니 이론적인 부분보다는 예제를 제시하며 실무위주로 설명을 하도록 하겠다.

자 그럼 일단 제가 예전에 만들어두었던 게시판의 리스트 페이지를 보도록 합시다.

<%

' Title   : List.asp
' Feature : 리스트를 처리하고 페이지 네비게이션을 표시한다.
' Purpose : 게시판의 리스트페이지
' Author  : 2001-05-17 by LikeJAzz

' 변수선언을 강요한다.
Option Explicit

' 사용할 변수선언
Dim intPage, intPrevNext, intRow, intStartPage, intTotalPage, I
Dim strListPageName

' 사용할 객체의 선언 ASP 는 Variant 형만 선언할수있다.
Dim oConn, oCmd, oRs

' 표시할 페이지를 Request 한다.
intPage = Cint(Request.QueryString ("intPage"))
If intPage = 0 Then intPage = 1

' 현재 페이지 이름
strListPageName = "List.asp"
' 페이지 Navigation 표시수
intPrevNext = 10
' 한페이당 출력 글수
intRow = 10

' 시작 페이지 계산
intStartPage = Int(intPage/intPrevNext) + 1
If intPage MOD intPrevNext = 0 Then intStartPage = intStartPage - 1
intStartPage = (intStartPage -1) * intPrevNext + 1

' Connection 객체 생성
Set oConn = Server.CreateObject ("ADODB.Connection")
' ODBC 로 연결하여 오픈한다.
oConn.Open "dsn=test;uid=sa;pwd="

' 리스트를 뽑아올 StoredProcedure 사용을 위해 Command 객체 생성
Set oCmd = New ADODB.Command
With oCmd
.ActiveConnection = oConn

.CommandType = adCmdStoredProc
.CommandText = "SP_BOARD_LIST"
.Parameters.Append.CreateParameter("PAGE", adInteger, adParamInput, , intPage)
.Parameters.Append.CreateParameter("ROW_COUNT", adInteger, adParamInput, , argRow)
.Parameters.Append.CreateParameter("TOTAL_PAGE", adInteger, adParamOutput, , 0)

' 리턴변수값을 받기위해 실행한다. (페이징을 위해 필요) .Execute

intTotalPage = oCmd.Parameters(0).Value
' 리턴되는 레코드셋을 받기위해 한번 더 실행한다.
Set oRs =.Execute
End With Set oCmd = Nothing ' 리스트 표시 시작. 레코드셋이 EOF 가 될때까지 반복되며 리스트를 출력해준다. Do Until oRs.EOF %> // 리스트 내용이 주욱 표시되는 부분. <% oRs.MoveNext Loop %> // 여러 HTML 요소들이 표시되는부분. <% ' Page-Navigation 이 표시되는 부분. If intTotalPage > intPrevNext Then If intStartPage = 1 Then Response.Write " ◀ " Else Response.Write " <a href=" & strListPageName & _ "?intPage=" & intStartPage - 1 & _ "> ◀ </a> " End If For I = intStartPage To intStartPage + intPrevNext - 1 If I > intTotalPage Then Exit For Else If I = intPage Then Response.Write " <font color=red>" & I & "</font> " Else Response.Write " <a href=" & strListPageName & _ "?intPage=" & I & _ "> " & I & " </a> " End If End If Next If (intStartPage + intPrevNext > intTotalPage) Then Response.Write " ▶ " Else Response.Write " <a href=" & strListPageName & _ "?intPage=" & I & _ "> ▶ </a> " End If Else Response.Write " ◀ " For I = intStartPage To intTotalPage If I = intPage Then Response.Write "<font color=red> " & I & " </font>" Else Response.Write " <a href=" & strListPageName & _ "?intPage=" & I & _ "> " & I & " </a> " End If Next Response.Write " ▶ " End If %>

위의 asp 소스를 Visual Basic 으로 COM+ 컴포넌트를 작성하여 묶어보도록 하겠다.

소스에 대한 설명은 위 처럼 그때그때 직접 주석으로 표시하도록 하겠다. 하지만 실제로 저처럼 무리하게 주석을 표시할 필요는 없다. 선언부와 로직처리부분, 표현되는부분 정도만 분리해서 표시하면 될것이다.

간단히 위의 소스에 대해 설명을 하자면 앞부분은 리스트 표현을 위한 선언부와 약간의게시판 로직. 아래부분은 페이지 네비게이션이 표시되는 부분이다.

네비게이션은 웹에서 그림1 처럼 표현된다.

그림1

일반적인 asp 페이지의 경우 html 태그들 사이에 asp 코드가 위치하게 된다. 게시판처럼 조금은 복잡한형태 혹은 더 복잡한 로직들이 존재하는 페이지라면 소스 자체가 상당히 지저분해지고 디자이너와의 공동작업시 실수로 asp 코드들을 건드리는 상황도 발생한다. 그래서 우리는 저 로직들을 철저히 숨기고 될수있는한 깔끔한 asp 페이지를 만들어보도록 하겠다.

자 그럼 위의 ASP 코드를 Componet 로 묶기전에 약간의 부연설명을 곁들여보겠다.

크게 Component 사용형태는 2가지로 나뉜다.

1. 값을 전달받고 로직을 처리후 다시 결과값을 리턴해주는 형태. (일반적인 형태)
2. Component 에서 로직처리후 ASP 인터페이스를 이용하여 직접 출력까지하는 형태. (ISAPI 같은 형태)

방법론에 따르면 비지니스로직과 프리젠테이션로직을 완전히 분리해야 한다. 즉 Component 는 말그대로 로직만을 처리하고 그 결과값을 리턴해주는 1번 방법이 정석이다.

하지만 실제로 그렇게 구현을 하다보면 오히려 프리젠테이션 로직이 더 복잡해지는 경우가 있다. GetRows 로 레코드셋을 배열로 리턴해오면 가로세로가 뒤바뀌며 그 처리를 숫자로만 해야하므로 상당히 헷갈리게 된다. 또한 위의 Page Navigation 같은 부분은 Component 로 묶을수 없으므로 실제로 COM+ 을 사용하는 잇점을 살리지 못한다.

그래서 우리는 로직과 밀접한 관련이 있는 출력부분까지 COM+ 에서 처리하게끔 2번 방법으로 작성해보고자 한다. 여기서 Microsoft 에서 제시하는 Component 를 작성함으로서 얻게되는 잇점을 잠깐 살펴보겠다.

1. Perfomance and scalability : 이진형태의 코드이므로 interpreting 에 비해 더 빠르고 더 적은 메모리를 요구한다.
2. Business logic encapsulation : 코드를 객체지향화 해주며 디버깅, 배포, 업그레이드를 더 쉽게 해준다. 또한 여러 애플리케이션간에 재사용이 가능하다.
3. Separation of data and user interface (UI) : 비지니스 로직과 데이타를 건들지 않고 UI 를 쉽게 개선할수있다. 빠르게 급변하는 Web 애플리케이션에서 중요한 부분이다.

기술을 만든 벤더에서 제시하는 내용이므로 너무 장점만을 부각시키려 하고 있다. 하지만 실제로 Component 를 구현함으로 인해 여러가지 단점도 발생한다.

프리젠테이션 로직을 쉽게 개선할수있다고 하지만 만약 비지니스로직이 변경될경우 (+1 을 계산하는 로직인데 +2 를 해야할경우) dll을 이진호환성으로 재컴파일 해야한다. IIS 를 중지시키고 구성요소서비스에서 해당 COM+ 애플리케이션을 시스템종료 시킨후 해당 dll 파일을 교체하고 다시 IIS 를 되살려야 한다.

로직이 변경될때마다 이 작업을 반복해야한다는건 상당히 번거롭다. 무정지시스템을 구현해야하는 웹서비스라면 치명적이다. 이외에도 자칫 잘못하다가는 Versioning 문제가 발생한다. 한때 악명높던 DLL Hell 을 기억하시는지? 그래서 Wrox 의 Professional Active Server Pages 3 에서언급한 컴포넌트의 단점에 개인적인 사견을 덧붙여 아래와 같이 정리해 보았다.

1. 컴포넌트는 디버깅이 더 힘들다. : 스크립트 디버깅이 불가능하다. 디버깅을 위해 WinDBG 등의 프로그램을 사용한다면 배보다 배꼽이 더 큰 경우가 아닐까 ?

2. 컴포넌트는 수정하기 더 힘들다. : asp 페이지는 수정후 단순히 저장만 하면 바로 적용되지만 컴포넌트는 서비스를 내린후 재 컴파일 과정을 거쳐야 한다. 이는 편집-실행-디버그 사이클을 길게 만든다.

3. 어설프게 개발된 컴포넌트는 다운된다. : 버그가 많은 컴포넌트는 asp 애플리케이션을 다운시킬수 있다. 전적으로 스크립트와 시스템 컴포넌트로 구성되어있는 asp 애플리케이션(즉, VB 수준의 컴포넌트)은 거의 다운되지 않는다. 저자는 asp 애플리케이션을 High-isolated (격리됨) 으로 설정하고 컴포넌트를 라이브러리 패키지로서 실행시킬것을 권장한다.

4. 어설프게 개발된 컴포넌트는 Memory Leakage (메모리누수) 를 발생시킨다. : 자원을 제대로 반환해주지 않는다면 메모리를 비롯한 다른 자원들을 누수시킬수 있다. 이런 현상이 오래 지속되면 컴포넌트는 웹서버를 사용 불가능 상태로 만들 수도 있다. (일반적으로 VB 수준의 ADO 로 구성된 컴포넌트에서는 이런일이 발생하지 않는다.)

5. 어설프게 개발된 컴포넌트는 높은 스트레스를 받는 상황에서 견뎌내지 못한다. : WAST(Web Application Stress Tool)로 스트레스 테스트를 거칠것을 권장한다. 특히 멀티프로세서 시스템(2cpu 이상)에서 Dead-Lock 과 Access-Violation 은 주의해야 한다.

6. 많은 컴포넌트들은 스레드 연결성을 가진다. : 컴포넌트가 Session 이나 Application 객체안에 저장될때 잘 작동하지 않는다. (물론 잘 작동한다해도 이는 추천하지 않는 행동이다.) 특히 VB, MFC 로 작성된 컴포넌트가 그렇다 . VB 는 아직 Neutral 이나 Both-threaded 를 지원하지 않는다.

7. 컴포넌트는 종종 멀티프로세서 시스템들로 확장되지 않는다. : Lock 을걸고 Thread-safe 로 작동하므로 단일프로세서(1 cpu)에서는 잘 작동하지만 멀티프로세서 시스템(2 cpu 이상)에서는 Serializable 을 발생시킬수 있다 .

8. 그외 많은 페이지들이 컴포넌트로 변환시킬만한 가치를 가지지 않는다. : 작은 페이지나 어쩌다 한번 실행되는 페이지들은 컴포넌트로 재가공할 필요가 없다. 어짜피 그들을 컴포넌트로 변환시켜도 시스템의 성능이 확연하게 개선되지 않는다. 로그를 분석후 어떤 페이지를 컴포넌트로 변환시킬지 찾아보라.


대략적인 법칙 : 적어도 100줄 이상의 스크립트가 있으며, 그 스크립트안에 몇개의 큰 순환 루프들이 들어있지 않는 한 그 페이지를 컴포넌트로 변환시킬 필요는 없다.

위에 언급한 것들 중에서 최소한 Visual Basic 으로 컴포넌트를 작성하는 이 글에서 고려해야 할 사항은 1번, 2번, 8번 정도가 되겠다.하지만 4번의 경우 객체를 제때 반환해주는것은 조은습관이며 차후 Visual C++ 의 ATL 을 사용해 저수준의 컴포넌트를 작성할때에도 많은 도움이 된다. 또한 6번의 경우 Session, Application 에 컴포넌트 객체를 담아두는것은 추천하지 않는다. (그렇게 구현해야만 하는 경우도 존재하지 않는다.) 물론 FTA(Free-Threaded Apartment), NTA(Neutral-Threaded Apartment) 는 현재의 Visual Basic 에선 구현할수도 없다.

대략적인 법칙에 언급된것처럼 컴포넌트화 해야하는 경우를 추려본다면 10만 이상의 트래픽을 지닌 사이트에서 로그인, 게시판, 쇼핑카트 정도에 구현하는것을 추천한다. 성능개선 효과를 얻을수 있을것이다.

보통 게시판은 로직 하나로 인자값만 달리하여 다양한형태로 구현해내게 되는데 아이러브스쿨같이 글수가 1000만을 넘어가고 사용자의 액세스가 빈번한 경우(아마 트래픽의 대부분일듯)라면 게시판을 컴포넌트로 작성하게 된다면 상당한 효과를 얻을수 있을것이다. (아마도 그렇게 작성했을 것이다.)

물론 위의 글은 UML 방법론을 전혀 고려하지 않은 철저히 퍼포먼스 위주로 언급한 글이다. 개인적인 의견은 아직은 UML 을 적용한다고 뚜렷한 이득을 볼수없으며 오히려 디버깅 사이클을 더 길게 만들어 유지보수에 더 곤란을 겪을것이라 생각한다. 물론 모델링이란 측면에서 본다면 충분히 가치있는 일이지만 퍼포먼스측면에서 본다면 아직이다라는 소리다. 물론 COM+ 의 성능은 지속적으로 개선되고 있으며.NET 이후에 객체지향방법론은 확실히 자리 잡을것이다.

하지만 현재로서는 클라이언트나 개발자에게나 가장 중요한것은 퍼포먼스 이기에 주로 퍼포먼스 위주로 언급을 하겠다.

사설이 길었다. 코드 한줄 안보여주고 설명으로만 때우려는 사람을 나역시도 무척 싫어한다. ^^; 하지만 기초와 이론은 중요한법. 탄탄한 기본기위에 고난이도의 기술을 구현할수있다는 사실을 명심하자.

자 그럼 직접 위에 언급한 소스를 가지고 Component 를 구현해보도록 하겠다. 비베로 Component 를 만드는 방법에 대해서는 안다는 가정하게 진행하도록 하겠다. 상세한 자료는 태요님강좌와 데브피아등에서 많은 정보를 얻을수있을것이다.

우선 VB 컴포넌트 소스이다. 프로젝트명은 bc_Board 로 하고 클래스명은 List 로 하겠다. 그대로 클래스모듈에 바로 코딩하면 된다. SELECT 만 할것이므로 트랜잭션은 1. No Required 로 지정한다.


' Title : 게시판 리스트 컴포넌트
' Feature : 리스트를 처리하고 페이지네비게이션을 표시한다.
' Author : 2001-05-21 by LikeJAzz

' 참조해야할것 :
' 1. Microsoft Active Server Pages Object Library 를 참조한다.
' 2. Microsoft ActiveX Data Object 2.5 Library (2.6도 당연히 무방)를 참조한다.
' 3. COM+ Services Type Library 를 참조한다.

' 변수선언 강요
Option Explicit
' ObjectControl 을 사용한다. Activate, Deactivate, CanBePooled 등의 이벤트를 사용할수있다
Implements ObjectControl Private oContext As ObjectContext
' 사용할 ODBC 명을 상수로 정의한다.
' 좀더 유동적인 처리를 위해 값을 레지스트리에 저장하거나
' 좀더 빠른처리를 위해 OLE-DB를 사용해도 무방하다.

Const CONNECT_STRING = "dsn=test;uid=sa;pwd="
Dim oConn As ADODB.Connection
' 사용할 asp 객체를 미리 선언해둔다.
Dim oResponse As Response
Dim oRequest As Request Dim intTotalPage As Integer, intStartPage As Integer
Dim intPrevNext As Integer, intPage As Integer
Public Function ShowMeListPage(ByVal argPage As Integer, _
ByVal argPrevNext As Integer, _
ByVal argRow As Integer) As Variant

On Error GoTo ErrHandler

' Response, Request, Server, Application, Session 등의 asp 객체를 사용하고자
' 할경우 MTS 없이 사용하면 오류가 발생한다.
' 이는 MTS 없이는 컴포넌트가 Context 를 관리할수 없기때문이며, 어떤 클라이언트에게
' asp 구문을 수행해야 하는지 알길이 없기 때문이다.
' 아래와 같이 Context 내에서 객체를 호출해야 MTS Excusive API 가 작동되며 컴포넌트가
' asp 페이지의 Context 에 접근하고 원하는 asp 의 기능을 직접 컴포넌트내에서
' 사용할수가 있다.

Set oResponse = oContext("Response")
Dim oCmd As ADODB.Command
Dim oRs As ADODB.Recordset
intPage = argPage
intPrevNext = argPrevNext

' 시작페이지 계산
intStartPage = Int(intPage / intPrevNext) + 1
If intPage Mod intPrevNext = 0 Then intStartPage = intStartPage - 1
intStartPage = (intStartPage - 1) * intPrevNext + 1
' 리스트를 반환하는 StoredProcdure를 사용한다.
Set oCmd = New ADODB.Command
With oCmd
.ActiveConnection = oConn

.CommandType = adCmdStoredProc
.CommandText = "SP_BOARD_LIST"
.Parameters.Append.CreateParameter("PAGE", adInteger, adParamInput, , intPage)
.Parameters.Append.CreateParameter("ROW_COUNT", adInteger, adParamInput, , argRow)
.Parameters.Append.CreateParameter("TOTAL_PAGE", adInteger, adParamOutput, , 0)

' 리턴변수값을 받기위해 실행한다. .Execute

intTotalPage = oCmd.Parameters(0).Value
' 리턴되는 레코드셋을 받기위해 한번 더 실행한다.
Set oRs =.Execute
End With
Set oCmd = Nothing
' 레코드셋을 배열로 반환하여 리턴해준다.
ShowMeListPage = oRs.GetRows
' 다른 메소드에서 사용할 인자값을 전달시켜주기 위해 쿠키를 사용한다.
' 원래 일반적인 COM 컴포넌트의 경우 메소드간에 혹은 메소드와 프로퍼티간에
' 인자값 전달이 가능한데 COM+ 에 올린 상태에서는 어떤방법을 써도 메소드간에
' 인자값을 전달시킬수 없었다.
' 결국 쿠키를 사용했고 별로 깔끔하지 못한 방법이 되었다. 원인과 해결책을 ' 아시는분은 메일주시면 감사. ^^;

oResponse.Cookies("Board")("intTotalPage") = intTotalPage
oResponse.Cookies("Board")("intPrevNext") = intPrevNext
oResponse.Cookies("Board")("intStartPage") = intStartPage
oResponse.Cookies("Board")("intPage") = intPage

oContext.SetComplete

Set oRs = Nothing
Set oCmd = Nothing

Exit Function

ErrHandler:
oContext.SetAbort
Set oRs = Nothing
Set oCmd = Nothing
' 에러가 발생할경우 에러메시지를 반환한다.
Err.Raise Err.Number, Err.Source, Err.Description
End Function

Private Sub ObjectControl_Activate()
On Error GoTo ErrHandler
Set oContext = GetObjectContext
' 퍼포먼스 향상을 위해 Early Binding 을 한다. (asp 에선 Late Binding 밖에 할수 없다.)
Set oConn = New ADODB.Connection

oConn.Open CONNECT_STRING oContext.SetComplete Exit Sub
ErrHandler:
oContext.SetAbort
' 에러가 발생할경우 에러메시지를 반환한다.
Err.Raise Err.Number, Err.Source, Err.Description
End Sub
Private Function ObjectControl_CanBePooled() As Boolean
' 이부분은 True이든 False든 아무런 효과를 줄수없다.
' 아직 Visual Basic 에선 Object Pooling 이 되지 않기 때문이다.

ObjectControl_CanBePooled = False
End Function

Private Sub ObjectControl_Deactivate()
' 열린상태라면 닫고 개체를 반환한다.
If oConn.State = adStateOpen Then oConn.Close
Set oConn = Nothing
Set oContext = Nothing
End Sub

Public Sub ShowMePageNavigation(ByVal strListPageName As String)
Dim I As Integer
' 사용할 asp 객체를 Context 내에서 호출한다.
Set oResponse = oContext("Response")
Set oRequest = oContext("Request")
' 쿠키에서 ShowMeListPage 에서 처리했던 인자값들을 불러온다.
intTotalPage = oRequest.Cookies("Board")("intTotalPage")
intPrevNext = oRequest.Cookies("Board")("intPrevNext")
intStartPage = oRequest.Cookies("Board")("intStartPage")
intPage = oRequest.Cookies("Board")("intPage")
' Page-Navigation 이 표시되는 부분.
If intTotalPage > intPrevNext Then
If intStartPage = 1 Then
oResponse.Write " ◀ "
Else
oResponse.Write " <a href=" & strListPageName & _
"?intPage=" & intStartPage - 1 & _
"> ◀ </a> "
End If For I = intStartPage To intStartPage + intPrevNext - 1
If I > intTotalPage Then
Exit For
Else
If I = intPage Then
oResponse.Write " <font color=red>" & I & "</font>"
Else
oResponse.Write " <a href=" & strListPageName & _
"?intPage=" & I & _
"> " & I & " </a> "
End If
End If
Next If (intStartPage + intPrevNext > intTotalPage) Then
oResponse.Write " ▶ "
Else
oResponse.Write " <a href=" & strListPageName & _
"?intPage=" & I & _
"> ▶ </a> "
End If
Else
oResponse.Write " ◀ "

For I = intStartPage To intTotalPage
If I = intPage Then
oResponse.Write "<font color=red> " & I & "</font>"
Else
oResponse.Write " <a href=" & strListPageName & _
"?intPage=" & I & _
"> " & I & " </a> "
End If
Next
oResponse.Write " ▶ "
End If
Set oResponse = Nothing
Set oRequest = Nothing
oContext.SetComplete End Sub

다 작성하여 dll 을 만들었다면 구성요소서비스에 COM+ 로 등록을 시켜줘야 한다. ObjectContext 를 사용하였으므로 등록시키지 않고 사용하려 한다면 오류를 발생할것이다. 등록하는법에 관해서는 여러곳에 자료가 많으니 자세한 내용은 생략하겠다. (죄송ㅡ_ㅡ)

다음은 리스트를 불러오는 Stored Procedure 의 소스이다. (원래의 asp 페이지에서도 사용한다.)

/* Title : SP_BOARD_LIST 
Feature : 게시판 리스트에 쓰일 레코드셋과 전체페이지수를 리턴한다.
Author : 2001-05-21 by LikeJAzz */

CREATE PROCEDURE SP_BOARD_LIST
@PAGE INT,
@ROW_COUNT INT,
@TOTAL_PAGE INT OUTPUT
AS
DECLARE @SQL VARCHAR(150)
DECLARE @TOTAL_RECORDS INT
SELECT @TOTAL_RECORDS = COUNT(*) FROM tblTEST
SET @TOTAL_PAGE = CEILING (@TOTAL_RECORDS / @ROW_COUNT)

/* ADO 의 RecordCount, AbsolutePage 등의 속성을 쓰지 않고 DB tier 에서 원하는 만큼 의 레코드셋을 뽑아내게끔 쿼리를 구성했다. 태요님 강좌에 피드백남겨주신분의 쿼리를 써보았는데 꽤 유용했다. 감사 ^^; */
SET @SQL = 'SELECT TOP ' + CONVERT(VARCHAR(10), @ROW_COUNT)
SET @SQL = @SQL + ' field1, field2, field3 FROM (SELECT TOP '
SET @SQL = @SQL + CONVERT(VARCHAR(10), (@TOTAL_RECORDS - (@PAGE - 1) * @ROW_COUNT)) SET @SQL = @SQL + ' field1, field2, field3 FROM tblTEST ORDER BY seq ASC) A '
SET @SQL = @SQL + 'ORDER BY A.field1 DESC'

EXEC (@SQL)

자 그럼 이제 결론을 내보자. 과연 asp 페이지는 얼마나 깔끔해 졌을까 ? 아래처럼 되었다.

<%

' Title   : List.asp
' Feature : 리스트를 처리하고 페이지 네비게이션을 표시한다.
' Purpose : 게시판의 리스트페이지
' Author  : 2001-05-17 by LikeJAzz

' 변수선언을 강요한다.
' Option Explicit

' 사용할 변수선언
Dim intPage, intPrevNext, intRow, intStartPage, intTotalPage, I
Dim strListPageName

' 사용할 객체의 선언 asp 는 Variant 형만 선언할수있다.
' Dim oConn, oCmd, oRs

' 표시할 페이지를 Request 한다.
intPage = Cint(Request.QueryString ("intPage"))
If intPage = 0 Then intPage = 1

' 현재 페이지 이름
strListPageName = "List.asp"
' 페이지 Navigation 표시수
intPrevNext = 10
' 한페이당 출력 글수
intRow = 10

Dim arrRs

' 컴포넌트를 호출한다.
Set oBoard = Server.CreateObject ("bc_Board.List")
' Getrows 로 리턴된 레코드셋을 배열에 받아낸다.
arrRs = oBoard.ShowMeListPage(intPage, intPrevNext, intRow)


' 리스트 표시 시작. 레코드셋이 EOF 가 될때까지 반복되며 리스트를 출력해준다.
For I = 0 To Ubound(arrRs, 2)
%>


// 리스트 내용이 주욱 표시되는 부분.


<%
  ' 출력할때는 아래와 같이 출력한다. (가로세로가 바뀜에 주의하자)
	Response.Write arrRs(0, I)
Next %> // 여러 HTML 요소들이 표시되는부분. <% ' Page-Navigation 이 간단히 메소드 호출로 표시된다. oBoard.ShowMePageNavigation(strListPageName) Set oBoard = Nothing %>

asp 코드가 한결 깔끔해졌다.

로직을 실수로 건드릴 염려도 없고 디자인이 다른 같은형식의 리스트 페이지라면 컴포넌트의 재사용도 가능하다. 물론 트래픽이 많은 페이지라면 컴포넌트로 인해 퍼포먼스도 상당히 향상될것이다.


unsolved Problem :

컴포넌트내의 메소드와 프로퍼티간에 인자값 전달이 되지 않는다. 쿠키를 사용하는 조금은 지저분한 방법으로 해결했지만 분명 COM+ 에 올린 상태가 아닌 일반적인 COM 컴포넌트에서는 같은 클래스라면 메소드와 프로퍼티간에 변수값이 전달된다. 하지만 COM+ 상태에서는 서로 다른 메소스들끼리 인자값을 전달시켜주지 못했고 결국 쿠키로 전달이라는 극단적인 방법밖에 취할수가 없었다. 원인과 해결책을 아시는분은 메일주세요 ^^;

이상으로 간략하게나마 강좌를 마친다. 휴 역시 강좌를 적는다는건 글을 적는다는건 힘든일이다. 이글을 적으면서도 얼마나 많이 생각하면서 글을 적었는지 모르겠다.

꾸준히 글을 올려주시는 태요님이 존경스러울뿐이다.

앞으로 기회가 닿는다면 msdn 의 샘플사이트 Duwamish Online 을 분석한글 혹은 Visual C++ 의 ATL 을 사용하여 가장 최적화된 컴포넌트 작성법에 대해 강좌를 적어볼 생각이다.

아무쪼록 부족한 제글을 읽어주신 여러분들께 감사드리며 피드백은 이메일 likejazz@korea.com 이용해주시면 됩니다. 강좌에 대한 내용외에 질문들은 되도록이면 자제해주셨으면 좋겠습니다. 죄송 ^^;

그럼 다음에 만날때까지 Happy Programming!

참조서적

Professional ASP Data Access (Wrox)
Professional Active Server Pages 3 (Wrox)
UML Components (Addison-Wesley)
Mastering Enterprise Development Using Microsoft Visual Basic 6.0 (Microsoft Press)
ADO & MTS Programming (대림출판사, 인브레인)
Taeyo's Advanced ASP to be Professional (정보문화사, 김태영님^^;)

참조사이트

Developing a Visual Basic Components for IIS/MTS
http://msdn.microsoft.com/workshop/server/components/vbmtsiis.asp

Handling Arrays Between ASP and COM
http://www.15seconds.com/issue/990826.htm

Platform SDK Documentation on COM+
http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/cossdk/complusportal_9o9x.htm

ASPToday , Wrox 에서 운영하는 이곳에 조은 자료가 많다. 하지만 유료화가 되었다. 슬프다 T_T
http://www.asptoday.com/


객체지향 뉴스레터

http://sslab.icu.ac.kr/oonews/


authored by


 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})