'개발/.NET'에 해당되는 글 13건

  1. 2008.12.15 INotifyPropertyChanged 인터페이스 소개
  2. 2008.12.02 닷넷 트랜잭션 정리 2
  3. 2008.11.28 닷넷 Event 정리 1

INotifyPropertyChanged 인터페이스는 WPF를 하면서 처음 알게되었는데 MSDN에서 이 인터페이스에 대해서 검색을 해보면 .NET 프레임워크 2.0에서 새로 추가된 인터페이스인 것을 알 수 있다. 이 인터페이스는 그 이름대로 프로퍼티가 변경되었음을 알려주는 역할을 한다. 예제를 보기에 앞서 데이터 바인딩에 대한 간단히 알아보면 데이터 소스와 데이터가 바인딩 되는 대상이 있다. 예를 들어서 DB에 직원 정보로 가져온 데이터를 List<Employee>에 넣어 DataGridView 컨트롤에 바인딩 한다고 생각을 해보자. 여기서의 데이터 소스는 List<Employee>이고 데이터 대상은 DataGridView 컨트롤이다.

다음은 INotifyPropertyChanged 인터페이스를 상속받아서 PropertyChanged를 구현한 예이다.
public class DemoCustomer : INotifyPropertyChanged

{

    public DemoCustomer() { }

 

    private string customerName = String.Empty;

 

    public string CustomerName

    {

        get { return customerName; }

        set

        {

            customerName = value;

            OnPropertyChanged("CustomerName");

        }

    }

 

    public event PropertyChangedEventHandler PropertyChanged;

 

    protected virtual void OnPropertyChanged(String info)

    {

        if (PropertyChanged != null)

            PropertyChanged(this, new PropertyChangedEventArgs(info));

    }

}

=> 구현하는 방법은 좀 더 다양한 방법이 있지만 이 방법이 가장 심플해보이는 방법이다. 여기서 급 이번 포스트를 마무리해야 할 일이 생긴다. MSDN에 있는 예제를 실행해서 WPF가 아닌 닷넷2.0기반에서 소스를 변경하여 데이터 대상를 변경하려고 하면 PropertyChanged가 계속 null로 찍혀서 값은 변경이 되었지만 화면에는 변경이 되지 않는다.(바로 이 인터페이스의 가장 큰 역할은 소스를 변경해주면 대상에서도 자동으로 변경을 주는 것이다.) 이유를 찾기 위해서 여러가지 방법을 동원해서 알아보았지만 2.0에서는 이 인터페이스를 사용하지 말아야겠다는 결론만을 얻었다.

다음은 이 인터페이스를 구현해서 사용한 방법을 통해서 알게된 사실이다.
1. List<>를 DataGridView.DataSource 프로퍼티에 바인딩 하였을 경우에 포커스가 있는 로우의 경우에는 PropertyChaged가 null이 아니였다. 하지만 해당 로우에 포커스가 없으면 PropertyChaged가 null이고 화면에서는 변경된 사항을 알수가 없다.
2. 소스를 통해서 대상을 변경을 할 수 없다면 이 인터페이스를 사용하는 의미는 그렇게 없다고 생각이 되며 소스가 변경이 될때마다 데이터 대상에 null를 넣어주고 다시 변경된 데이터 소스를 바인딩해주는 방법을 사용하는 편이 낫다는 생각이 들었다.(List<>의 바인딩 속도는 건수가 많더라도 엄청나게 빠르다)

이번 포스트는 여러가지 테스트와 열심히 검색해봤지만 그닥 성과가 없어 상당히 아쉽다. 왜 2.0에서 INotifyPropertyChanged를 사용할 수 있게 해놓고 이런 제약조건(?)를 두어서 사용하기 힘들게 해놨는지 이해가 되지 않는다.

P.S : 제가 잘못 이해하여 오해(?)하고 있는 부분이 있다면 댓글을 통해서 알려주셨으면 합니다~

// 2009년 8월 6일
msdn 매거진에 아래와 같은 내용이 있습니다.

http://msdn.microsoft.com/ko-kr/magazine/cc794276.aspx
INotifyPropertyChanged 인터페이스를 사용할 경우 알아야 할 점이 있습니다. 이 인터페이스에 필요한 것은 PropertyChanged라는 이벤트뿐인데, 클래스가 이 이벤트를 발생시킨다는 보장이 없습니다. 많은 경우 클래스는 일부 public 속성에 대해 이벤트를 발생시키지만 아닌 경우도 있습니다. 소스 코드에 액세스할 수 없는 경우에는 PropertyChanged 이벤트를 발생시키는 속성과 그렇지 않은 속성을 미리 확인할 수 있는 마땅한 방법이 없습니다.
Posted by resisa
,

이번 프로젝트를 하면서 트랜잭션에 대해서 다시 한번 생각해보게 되었고 아래의 사이트들을 통해서 좋은 정보를 얻었다.

트랜잭션에 대한 정리를 잘 해놓은 MS의 장현춘 부장님의 블로그 링크이다.
http://kingcrap.com/entry/닷넷-트랜잭션-정리

System.Transactions(TransactionScope)에 대해서 정리를 해놓은 드원테크놀로지의 유경상 수석님의 블로그링크이다.
http://www.simpleisbest.net/articles/996.aspx

위을 내용을 아주 간단히 요약을 해보겠다~
먼저 트랜잭션 처리는 1. 로컬 트랜잭션(수동) 2. 분산 트랜잭션(자동)으로 나뉜다. 두 가지의 방법은 서로 장단점있는데 속도의 측면에서는 로컬 트랜잭션이 편리성 측면에서는 분산 트랜잭션이 좋다. 하지만 TransactionScope를 사용하면 Promotion이라는 기능이 있고(TransactionScope는 트랜잭션이 발생할 때 로컬 또는 분산 트랜잭션인지를 자동으로 처리해주는데 로컬 트랜잭션으로 실행하다가 다른 DB에 접속을 하는 순간에 자동으로 분산 트랜잭션으로 전환이 되는데 이러한 것을 Promotion이라고 한다.) 이러한 Promotion은 MSSQL 2005, 2008에서만 지원을 한다고 한다.
이번에 내가 한 프로젝트에서 DB가 Oracle여서 TransactinoScope를 사용하려고 했더니 oramts.dll이 필요하다며 예외가 발생했다. Ora MTS를 설치하면 TransactionScope를 사용할 수 있었다.

Ora MTS에 대해서는 아래의 링크를 보자.
http://www.simpleisbest.net/archive/2005/08/23/208.aspx

다음은 Ora MTS를 다운받는 링크이다.
http://www.oracle.com/technology/software/tech/windows/ora_mts/htdocs/utilsoft.html

테스트 환경은 윈도우 서버 2003에서 Oracle 9i 클라이언트와 Ora MTS 9.2.0.7.0 버전을 사용해서 해본 결과 TransactionScope를 사용할 수 있었다. 위의 첫번 째 링크(장현춘님)에 가보면 비스타에서도 Ora MTS 10.2.0.4.0버전을 사용해서 분산 트랜잭션으로 MSSQL과 Oracle을 묶어 프로젝트에서 사용하고 있다는 말이 제일 마지막에 나온다. 하지만 비스타에서 Ora MTS(버전:10.2.0.1, 10.2.0.2) 설치 오류가 나서 테스트를 해볼 수가 없었고 Ora MTS 10.2.0.4.0버전을 구할 수도 없었다. 아마 무엇인가 문제가 있어서 배포를 잠시 중단한게 아닌가 싶다.

<<수정일자 : 12월20일>>
Ora MTS 10.2.0.4.0버전이 아니라 Oracle Database 10g Release 2 (10.2.0.4.0) Patch Set의 버전이다. Ora MTS는 10.2.0.2.0를 설치하면 된다. 또한 Ora MTS가 오류가 나는 것의 원인은 Office 2007 때문이였다. 설치를 하다가 javaw.exe프로세스가 종료되었다는 메시지와 함께 설치가 종료되는데 Office를 지우고 설치를 하면 설치가 된다. 이것이 설치되었다고 해서 비스타에서TransactionScope를 사용해서 분산 트랜잭션을 사용할 수 있는 것이 아니다. Oracle Database 10g Release 2 (10.2.0.4.0) Patch Set까지 설치해야한다. Oracle Meta Link에서 이것을 다운을 받을 수 있는데 Meta Link는 오라클과 계약을 맺어 인증번호가 있어야 사용할 수 있다. 패치까지 받고 테스트는 안해봤지만 아마도 될 것이다. 사용자등록을 했는데 관리자가 있어 패스워드를 받아야한다. 참 하나 해보기 힘들다. 차후에 패치를 받고 테스트를 마친후에 정리를 해야할꺼 같다.
Posted by resisa
,

닷넷 Event 정리

개발/.NET 2008. 11. 28. 08:58

WPF에서 이벤트의 라우팅을 공부하면서 Event에 대해서 정리를 해보자는 마음이 생겼다. 먼저 닷넷 2.0을 기준으로 이벤트에 대해서 정리를 해보고 다음에 기회가 되면 WPF의 이벤트 라우팅에 대해서 써보겠다.
정리하는 내용은 MSDN을 보고 내가 이해한 것을 바탕으로 작성했다.

http://msdn.microsoft.com/ko-kr/library/awbftdfh(VS.80).aspx

1. Event의 개요
 1) Event 게시
 2) Event 구독
 3) Event 처리
여기서 1)를 수행하는 클래스를 게시자라고 하며 2), 3)를 수행하는 클래스를 구독자라고 한다. 게시자나 구독자라는 용어보다는 위의 단계에 대한 이해하는 것이 더 중요하다.
간단한 예를 들어서 위의 단계를 적용시켜 보자. 폼에 버튼을 하나 올려놓고 버튼을 클릭(두번클릭)하면 Click 이벤트가 자동으로 구독(InitializeComponent())이 되고 비하인드 코드에 이벤트가 등록된 이후의 어떤식으로 이벤트를 처리할 것인지를 작성할 수 있는 메소드가 자동으로 만들어진다.

MSDN에서 Event에 대한 개요 중 첫번째 문장이다.

 게시자는 이벤트가 발생하는 시기를 결정하고 구독자는 이벤트에 대한 응답으로 수행되는 동작을 결정합니다.

=> 위의 예에서 보면 버튼(게시자)에서 Click이라는 이벤트가 발생하는 시기(말 그대로 Click하는 순간)를 결정하기 위해 Event를 게시하였기 때문에 Click 이벤트를 사용할 수 있다. 폼(구독자)에 올려진 버튼(게시자)의 Click 이벤트를 버튼을 더블클릭(구독)하고 Click 이벤트가 발생할 때의 수행되는 동작(핸들러)을 처리할 수 있다.

2. Event의 구독 및 취소
먼저 이미 게시되어 있는 Event를 구독하여 보자. 1번에서 처럼 버튼을 더블클릭함으로써 자동으로 이벤트를 구독할 수 있다. 하지만 여기서는 프로그래밍적으로 구독을 해보도록 하자.

public Form1()

{

    InitializeComponent();

 

    Load += new EventHandler(Form1_Load);

}

 

void Form1_Load(object sender, EventArgs e)

{

    //이벤트에 대한 응답으로 수행되는 동작
}

=> Load 이벤트를 구독하기 위해서 Load란 이름으로 게시된 이벤트명을 적고 += 라고 적고 Tab키를 누르면 그 뒤쪽으로 EventHandler라는 이름의 객체를 생성하여 Form1_Load메소드를 자동으로 델리게이트 해주는 것을 알 수 있다. EventHandler는 '3. Event의 게시'때에 살펴보고 먼저 Form1_Load()의 시그니처에 대해서 살펴보자. 첫번째 인자는 object형으로 이벤트를 발생시키는 객체를 참조하고 EventArgs는 이벤트 데이터로 데이터가 없다는 것을 나타낸다. 이벤트를 발생시키는 객체는 있어야 할꺼 같은데 EventArgs는 왜 필요한걸까? 다음 문장을 살펴보자.

private void button1_MouseDown(object sender, MouseEventArgs e)

{

    if (e.Button == MouseButtons.Left)

    {

        // 왼쪽 버튼을 눌렀을 경우의 동작 시키고 싶은 코드

    }

}

=> 이번에는 EventArgs가 아니라 MouseEventArgs이다. EventArgs를 이야기 하면서 이벤트 데이터가 없는 것이라고 하였다. MouseEventArgs는 EventArgs를 상속받아서 만들어졌고 뭔가 이벤트 데이터가 있다는 의미이다. if문을 보면 e.Button이라는 이벤트 데이터가 있어서 마우스 왼쪽 버튼을 눌렀을 경우에만 어떤 동작을 수행하려는 것을 알 수 있다. 이처럼 EventArgs는 특정 이벤트가 발생하였을 경우에 해당 이벤트 데이터를 제공함으로써 이벤트가 발생한 객체에 접근하지 않고도 제공된 데이터를 활용할 수 있다.

3. Event의 게시
Event를 게시하는 게시자 클래스이다. 델리게이트로 연결하는 부분과 닷넷 프레임워크 지침에 따른 것을 제너릭 부분을 제거하고 EventHandler부분에 대한 이해를 돕기 위해서 약간 수정하였다.

class Publisher

{

    public delegate void CustomEventHandler(object sender, EventArgs e);

    public event CustomEventHandler RaiseCustomEvent;

 

    public void DoSomething()

    {

        OnRaiseCustomEvent(new EventArgs()); 

    }

 
   protected virtual void OnRaiseCustomEvent(EventArgs e)

    {

        CustomEventHandler handler = RaiseCustomEvent;

 

        if (handler != null)

        {

            handler(this, e);

        }

    }

}

=> delegate로 선언된 CustomEventHandler는 메소드를 델리게이트 하기 위해서 반환형과 매개변수를 가지고 있다. 이렇게 선언된 CustomEventHandler는 event 키워드와 함께 게시자 클래스의 이벤트로 게시되는 것을 알 수 있다. 만약에 여기서 event 키워드를 빼면 어떻게 될까? 프로그램은 정상적으로 동작이 된다. 약간 의외의(?) 결과라고 처음에는 생각이 되었지만 event키워드는 그 이름처럼 delegate로 선언된 Handler를 이벤트로 게시해주는 일 이외는 하는 것이 없는 것이다. event키워드로 게시함으로써 해당 이벤트를 번개 모양의 이벤트로 알 수 있는 것이고 event키워드가 없으면 게시자의 멤버변수로써 파란색 볼(?)로 나타난다.
OnRaiseCustomEvent()를 살펴보면 꼭 이렇게 할 필요는 없지만 닷넷 프레임워크 지침에 따른거니 표준정도라고 생각하고 보자. 좀 더 이해하기 쉽게 바꾸면 다음과 같다.

protected virtual void OnRaiseCustomEvent(EventArgs e)

{
        if (RaiseCustomEvent!= null)

        {

            RaiseCustomEvent(this, e);

        }

}


OnRaiseCustomEvent()는 virtual로 선언될 것을 볼 수 있다. 이 메소드는 재정의가 가능하다는 의미이고 많이 낯이 익는다. On~으로 시작하는 메소드는 바로 이벤트보다 먼저 실행이 되는 메소드인 것이다. 그래서 우리가 이벤트를 구독하지 않고 On~메소드를 재정의하여서도 이벤트를 사용할 수 있는 것이다. 2번에서 구독해본 폼의 Load이벤트를 override 키워드와 On으로 시작하는 메소드중 OnLoad()를 찾으면 아래와 같은 코드를 자동으로 만들어준다.

protected override void OnLoad(EventArgs e)

{

    base.OnLoad(e);
   

    //이벤트에 대한 응답으로 수행되는 동작
}

=> 폼을 상속받았기 때문에 base인 Form의 OnLoad()를 호출해주는 것을 알 수 있고 2번에서 델리게이트를 이용해서 구독한 것과 똑같은 동작 코드를 작성해 넣을 수 있다.

마지막으로 게시자에서는 이벤트가 일어나는 시점을 결정한다고 하였는데 DoSomething()가 바로 그 역할을 하는 메소드이다. 앞에서도 말했듯이 새롭게 이벤트에 대응되는 메소드인 OnRaiseCustomEvent()를 여기서 호출을 해주고 있는 것을 알 수 있다.

Posted by resisa
,