2008.05.20 13:45

.NET Framework 3.5 Service pack이 출시되었습니다.
흔히 Service pack이라고 하면 말 그대로 무엇가 문제가 있었다든지 버그를 패치하기 위한 용도로
생각하기 쉽지만 이번에 나온 .NET Framework 3.5 SP는 호프집에서 오징어와 같이 가벼운 안주로 주로
받던 말그대로 "서비스"에 입각한 팩인 것이다.

이렇게 예기 하는 데에는 다 그 만한 이유가 있다.
수정되고 변경된 내용이 생각보다. 너무 많고 단순히 기능 개선이라기 보다는 새로 추가된 기능들도
눈에 많이 띄기 때문이다.

먼저 ASP.NET과 관련된 기능과 Visual Studio 2008을 위해서 HTML편집기와 관련한 기능들,
그리고 더욱 향상된 자바 스크립트 인텔리전트


ASP, WCF에 대한 지원 및 클라이언트의 지원 사항의 개선 등등 이로 헤아릴 수 없이 많은 부분들이 개선되었다.
그리고 결정적으로 WPF에 대해서도 많은 개선사항이 있는데 이런 각 각의 세세한 변화는 지속적인 아티클을 통해서 하나씩 알려드리도록 하겠습니다.

신고
2008.03.23 09:50


Visual Studio 2008에서 지원하고 있는 디자이너와 개발자의 협업과 제품 라이프 사이클의 관리 그리고 실버라이트와의 관게에 대해서 설명하고 있습니다.
신고
2008.03.22 08:26

Visual Studio 2008은 Web Programming에 있어서 다양한 편의성이 강화 되었습니다.
Split으로 디자인과 소스코드를 동시에 편집하게 해준다든지 혹은 자바 스크립트 디버깅과 같은
기능들은 정말 훌륭하게 향상되었습니다.
또 툴상에서 AJAX기 지원되기 때문에 비교적 쉽게 AJAX를 개발할 수 있다는
장점도 있습니다.

신고
2008.03.21 21:07

막상 편집된 동영상을 보니 마구 민망해져서 왜 이런걸 찍었나 하고
후회도 되지만 그래도 나름 유용한 동영상인데다가 꽤 유명한 사람들이 대게 출연하기 때문에
좀 망가져도 나쁘지 않은것 같습니다. ^^

이 동영상은 첫번째 동영상으로 Visual Studio 2008이 달라진 점에 대해서 설명하고 있습니다.
설명에는 롯데정보통신 연구소에 선임 연구원으로 있는 한용희 Microsoft MVP님이
수고하시고 계십니다.

신고
2007.12.25 02:15

C#소스의 문서화

.NET 2007.12.25 02:15

C# 소스를 문서화 하기 위한 툴은 여러개 있는 것 처럼 보이지만 막상 사용하려고 하면
생각만큼 선택의 여지는 넓지 않습니다.
닷넷채널 프레임웍의 도움말을 만들기 위해서 소스상의 주석을 가지고 문서화를 할 수 있는
방법들을 찾아 보았습니다.

우선 대부분의 문서툴에서는 Visual Studio에서 지원하고 있는 xml 포멧을 사용합니다.
Visual Studio에서는 주석문으로 잘 달아놓은 것들을 XML포멧으로 출력하는 기능을 가지고 있습니다.

사용자 삽입 이미지

<그림1> 솔류션 탐색기에서 속성을 선택
사용자 삽입 이미지
<그림2>XML문서 파일 출력 설정
사용자 삽입 이미지

<그림3>출력된 XML파일

<그림1~3>을 참조하면 Visual Studio 에서 주석문을 정리한 XML파일을 얻을 수 있습니다.
사용자 삽입 이미지
<그림4>XML파일의 내용
이 XML 파일을 가지고 대부분 문서를 생성할 수 있게 지원하는데
이전까지는 대표적으로 많이 사용했던 것이 바로 NDoc 입니다.
사용자 삽입 이미지
<그림5>NDoc 사이트

하지만 NDoc은 그 뛰어난 기능에 비해서 오픈소스 프로젝트의 한계인 참여율 저조를
극복하지 못하고 개발이 중단되었습니다. 그래서 닷넷프레임웍 2.0을 지원하지 못합니다.
사용자 삽입 이미지
<그림6>NDoc설치화면
사용자 삽입 이미지
<그림7>NDoc의 지원 프레임웍
그래서 두번째로 선택할 수 있는 것이 바로 Doxygen이라는 프로그램입니다.
이 프로그램은 사용하기가 생각보다 까다롭고 불편해서 일단은 사용 불가로 생각했습니다.
사용자 삽입 이미지
<그림8>한 블로그에서 소개하고 있는 Doxygen
사용자 삽입 이미지
<그림9>Doxygen 공식 사이트
사용자 삽입 이미지
<그림10>Doxygen 다운로드
사용자 삽입 이미지
<그림11>Doxygen 설치
사용자 삽입 이미지
<그림12>Graphviz 설치

결국 제가 선택한 툴은 Sandcastle입니다.
강력하면서도 적절한 툴이며 프레임웍도 2.0을 잘 지원하고 있습니다.

사용자 삽입 이미지
<그림13>Sandcastle의 설치
Sandcastle는 UI가 없습니다. 그냥 명령어 기반의 프로그램입니다. 때문에 좀더 원활하게
사용하기 위해서는 Sandcastle Help File Builder가 함께 필요합니다.

사용자 삽입 이미지
<그림14> Sandcastle Help File Builder
사용하는 방법은 아주 쉽기 때문에 일단 패스 합니다. ^^

신고
2007.12.23 23:32
닷넷채널 시즌2 작업을 하면서
1차 설계때 포함시켰던 Enterprise Library를 배제하기로 결정했습니다.
Enterprise Library는 일단 그 자체만으로도 상당히 버겁고 또 사용하지 않는 다수의 Class도
함께 가지고 가야 한다는 점 그리고 프레임웍 버전업때의 자유도 등을 고려해서
이번 작업에는 적절하지 않다는 판단을 하게 되었습니다.

그리고 기본적으로 System.EnterpriseService를 사용하는 것을  표준으로 채택하려고 했으나
닷넷 프레임웍 2.0에 새로 추가된 System.Transaction을 활용하는 것도 표준으로 함께 권장한다.
System.Transaction을 우선적으로 사용하고 필요한 곳에는 System.EnterpriseService를
함께 사용할 수 있도록 했습니다.

자료들을 찾아보면 대체적으로 System.Transaction이 좀더 가볍고 유연한 방법이라고 되어 있는
것 같습니다. 아무래도 새버전에 맞쳐서 나온것 이라서 그런것인지 모르겠습니다만
아무튼 우리도 System.Transactions을 우선적으로 사용하는 것으로 결정했습니다.

또 System.Transactions의 경우 SQL Server, ADO.NET, MSMQ, MSDTC를 모두 지원하는
유연함과 강력함을 가지고 있습니다.

System.Transactions의 경우 암시적으로 특정범위안의 모든 Database Handling을 하나의
Transaction으로 묶어서 처리할 수 있는데 <리스트1>소스에서 사용법을 볼 수 있습니다.

// This function takes arguments for 2 connection strings and commands to create a transaction 
// involving two SQL Servers. It returns a value > 0 if the transaction is committed, 0 if the 
// transaction is rolled back. To test this code, you can connect to two different databases 
// on the same server by altering the connection string, or to another RDBMS such as Oracle 
// by altering the code in the connection2 code block.
static public int CreateTransactionScope(
    string connectString1, string connectString2,
    string commandText1, string commandText2)
{
    // Initialize the return value to zero and create a StringWriter to display results.
    int returnValue = 0;
    System.IO.StringWriter writer = new System.IO.StringWriter();

    // Create the TransactionScope to execute the commands, guaranteeing
    // that both commands can commit or roll back as a single unit of work.
    using (TransactionScope scope = new TransactionScope())
    {
        using (SqlConnection connection1 = new SqlConnection(connectString1))
        {
            try
            {
                // Opening the connection automatically enlists it in the 
                // TransactionScope as a lightweight transaction.
                connection1.Open();

                // Create the SqlCommand object and execute the first command.
                SqlCommand command1 = new SqlCommand(commandText1, connection1);
                returnValue = command1.ExecuteNonQuery();
                writer.WriteLine("Rows to be affected by command1: {0}", returnValue);

                // If you get here, this means that command1 succeeded. By nesting
                // the using block for connection2 inside that of connection1, you
                // conserve server and network resources as connection2 is opened
                // only when there is a chance that the transaction can commit.   
                using (SqlConnection connection2 = new SqlConnection(connectString2))
                    try
                    {
                        // The transaction is escalated to a full distributed
                        // transaction when connection2 is opened.
                        connection2.Open();

                        // Execute the second command in the second database.
                        returnValue = 0;
                        SqlCommand command2 = new SqlCommand(commandText2, connection2);
                        returnValue = command2.ExecuteNonQuery();
                        writer.WriteLine("Rows to be affected by command2: {0}", returnValue);
                    }
                    catch (Exception ex)
                    {
                        // Display information that command2 failed.
                        writer.WriteLine("returnValue for command2: {0}", returnValue);
                        writer.WriteLine("Exception Message2: {0}", ex.Message);
                    }
            }
            catch (Exception ex)
            {
                // Display information that command1 failed.
                writer.WriteLine("returnValue for command1: {0}", returnValue);
                writer.WriteLine("Exception Message1: {0}", ex.Message);
            }
        }

        // The Complete method commits the transaction. If an exception has been thrown,
        // Complete is not  called and the transaction is rolled back.
        scope.Complete();
    }

    // The returnValue is greater than 0 if the transaction committed.
    if (returnValue > 0)
    {
        writer.WriteLine("Transaction was committed.");
    }
    else
    {
        // You could write additional business logic here, for example, you can notify the caller 
        // by throwing a TransactionAbortedException, or logging the failure.
        writer.WriteLine("Transaction rolled back.");
    }

    // Display messages.
    Console.WriteLine(writer.ToString());

    return returnValue;
}
<리스트1> 트랜젹션 범위를 사용하여 암시적 트랜잭션을 구현하는 예



새로운 TransactionScope 객체를 만들면 Transaction Scope가 시작됩니다. 위에서 볼 수 있는데로
using문장을 이용해서 사용범위를 한정해 주는게 좋습니다.





Transaction을 확정하기 위해서는 TransactionSope객체의 Complete()호출해야 합니다.
Complete()을 호출하지 않으면 Transaction이 완료되지 않고 Rollback되어 버립니다.
using문장을 이용해서 TransactionScope를 설정할 경우에 어떤 예외가 발생하면
TranscationScope의 Dispose()가 호출됩니다. TransactionScope의 경우 Dispose()가 호출되면
Transaction의 끝으로 간주해서 해당 Tracation의 상태에 따라서 확정이나 취소를 선택하게 됩니다.





void RootMethod()
{
     using(TransactionScope scope = new TransactionScope())
     {
          /* Perform transactional work here */
          SomeMethod();
          scope.Complete();
     }
}

void SomeMethod()
{
     using(TransactionScope scope = new TransactionScope())
     {
          /* Perform transactional work here */
          scope.Complete();
     }
}
<리스트2> 트랜젝션이 중첩
<리스트2>에서 처럼 Transcation을 중첩할 수도 있습니다.
이렇게 중첩했을 경우에는 모든 Transcation이 확정되지 않으면 일괄 취소됩니다.



TrancationOption을 사용했을 경우에는 옵션에 따라서 세가지로 동작이 달라집니다.


Required
를 사용하여 범위를 인스턴스화하고 앰비언트 트랜잭션이 있으면 범위는 이 트랜잭션에 참여합니다.
그러나 앰비언트 트랜잭션이 없으면 범위는 새 트랜잭션을 만들고 루트 범위가 됩니다.
이 값은 기본값입니다. Required를 사용하면 범위 내부의 코드는 루트 범위이거나 아니면 단순히 앰비언트 트랜잭션에 참여하는지에 따라 다르게 동작할 필요가 없습니다. 이 코드는
두 경우에 모두 동일하게 작동해야 합니다.

RequiresNew를 사용하여 범위를 인스턴스화하면 이 범위는 항상 루트 범위가 됩니다. 이 범위가 새 트랜잭션을
시작하면 해당 트랜잭션은 범위 내부의 새 앰비언트 트랜잭션이 됩니다.

Suppress를 사용하여 범위를 인스턴스화하면 앰비언트 트랜잭션이 있는지 여부에 관계없이 이 범위는
트랜잭션에 참여하지 않습니다. 이 값을 사용하여 인스턴스화된 범위에서는 항상 앰비언트
트랜잭션이 null입니다.


이 외에도 시간 제한이나 격리수준을 설정하는 방법으로 세세한 설정이 가능합니다.
자세한 내용은 http://msdn2.microsoft.com/ko-kr/library/ms172152(VS.80).aspx
참조하기 바랍니다.




한가지 TransactionScope의 결정적 시간 제한 옵션은 따로 있습니다.
machine.config에서 MachineSettingsSection에서 전체적인 설정이 이미 설정되어 있습니다.
따라서 여러분이 하는 설정도 machine.config의 제한 시간을 넘어가지 못합니다.
http://msdn2.microsoft.com/ko-kr/library/ms172152(VS.80).aspx
기본 타임아웃이 10분으로 잡혀 있다고 합니다. 따라서 여러분들이 시간을 아무리 늘려도
10분 이상을 설정할 수 없습니다. 만약 더 큰 시간이 필요하다면 machine.config의 내용을
수정해야 합니다


<system.transactions>
<defaultSettings distributedTransactionManagerName="NERPSVR" timeout="00:00:00" />
<machineSettings maxTimeout="00:00:00" />
</system.transactions>
<리스트3>Machine.config의 Transaction Timeout 설정
이 내용은 정성태님의 블로그에서 내용을 참조할 수 있습니다.
http://www.sysnet.pe.kr/Default.aspx?mode=3&sub=0&pageno=0&detail=1&wid=716





신고
2007.12.21 01:53
닷넷채널 시즌 2 작업을 위한 프레임웍 제작에 들어갔습니다.
일단은 그렇게 큰 작업과 복잡한 프레임웍을 제작할 것은 아니기 때문에
우선적으로 Web과 Windows를 동시에 지원하는 것으로 가닥을 잡고 준비하고 있습니다.

우선 간단히 네임스페이만 정리해 보았습니다.
사용자 삽입 이미지
<그림1>DNC Framework namespace

마음으로는 .NET Framework 3.0 이상을 사용하고 싶지만 호스팅 업체 사정상
어쩔 수 없이 프레임웍의 버전은 2.0으로 제한했습니다.
기반 서비스는 Microsoft의 Patterns & practices에서 제공하는 Enterprise Library를
사용하는 것으로 가닦을 잡았습니다.
아참에 Enterprise Library를 공부해 보겠다는 욕심도 함꼐 들었습니다.

아무튼 Enterprise Library는 2006 January Enterprise Libarary for .NET Framework 2.0
버전을 사용하기로 결정했습니다.
http://www.microsoft.com/downloads/details.aspx?familyid=5A14E870-406B-4F2A-B723-97BA84AE80B5&displaylang=en&hash=3U2vJPRkpncc5%2bVHbiTc6Nz9M0nkjlDz73r9Bau1mGj%2bQRcTvra0rLldpzp9TUvW0YgteS5RCuEAUdzILjwrHw%3d%3d

사용자 삽입 이미지
<그림2> Enterprise Library 다운로드

Enterprise Library가 버전이 올라가더니 설치화면도 훨씬 미려하게 잘 수정된것 같다.

사용자 삽입 이미지

<그림3> Enterprise Libarary설치

사용자 삽입 이미지

<그림4> 설치 옵션

지금은 네임스페이스마다 필요한 클래스를 도출하고 있는 중.. ^^
신고


티스토리 툴바