티스토리 툴바

블로그 이미지
kunami

카테고리

분류 전체보기 (79)
General Issue (19)
Oslo (10)
C# (4)
ASP.NET (3)
Spring.NET (13)
SQL Server 2008 (6)
WCF (1)
생각 (20)
Photo (3)
Total15,502
Today2
Yesterday11

5.3.3. 이벤트 리스너의 선언적인 등록

C# 의 이벤트는 event 키워드를 통해 제공된다. 아래는 이벤트 핸들러 메서드에 파라미터를 추가하는 델리게이트를 사용하는 이벤트의 단축 표기법이다.

 

public class EventSource

public event EventHandler Click;

 

.NET 이벤트를 사용하려면, 하나 이상의 이벤트 핸들러 메서드와 결합해야 한다. 각 핸들러 메서드는 특정 이벤트가 발생할 때 개체의 메서드에 접근되어 해당 이벤트를 프로그래밍 적으로 추가되거나 삭제된다. 이벤트에 하나 이상의 핸들러 메서드를 추가하면, 각 등록된 메서드는 이벤트가 발생할 때 차례로 호출된다.

 

TestObject source = new TestObject();

TestEventHandler eventListener1 = new TestEventHandler();

TestEventHandler eventListener2 = new TestEventHandler();

 

source.Click += eventListener1.HandleEvent; // Adding the first event handler method to the event

source.Click += eventListener2.HandleEvent; // Adding a second event handler method to the event

source.OnClick(); // First eventListener1.HandleEvent is invoked, then eventListener2.HandleEvent

 

OnClick() 이 호출 될 때, 이벤트가 발생한다.

 

public void OnClick()

{

    if (Click != null)

    {

        Click(this, EventArgs.Empty); // Fire the event off to the registered handler methods

    }

}

 

이벤트 사용 시, 나쁜 점 중에 하나는 늦은 바인딩을 사용하지 않고, 선언한 개체에 등록된 프로그래밍된 특정한 이벤트를 사용하는 것이다. Spring.NET 은 핸들러 메서드와 특정 이벤트를 등록하기 위해 <object> 엘리먼트안에 <listner> 엘리먼트를 사용하는, 선언적인 방법을 제공한다.

 

5.3.3.1. 이벤트 핸들러 선언

코드에 특별한 선언을 하기 보다는, 보통 개체 메서드의 어플리케이션 구성에 해당 이벤트를 선언하는 <listner> 엘리먼트를 사용하여 이벤트에서 호출되는 메서드를 추가할 수 있다.

listner 엘리먼트를 사용하면 아래와 같은 것을 할 수 있다.

l  이벤트가 발생할 때 호출하는 메서드 설정

l  정규 표현식 기반의 핸들러 메서드의 컬렉션 등록

l  정규 표현식을 포함한 이벤트 명에 대응하는 핸들러 메서드 등록

 

5.3.3.2. 이벤트 발생 시 호출할 메서드 구성

아래는 구성 파일에 <listner> 엘리먼트를 이용하여 같은 이벤트를 등록하는 예이다.

 

<object id="eventListener1" type="SpringdotNETEventsExample.TestEventHandler, SpringdotNETEventsExample">

    <!-- wired up to an event exposed on an instance -->

    <listener event="Click" method="HandleEvent">

        <ref object="source"/>

    </listener>

</object>

<object id="eventListener2" type="SpringdotNETEventsExample.TestEventHandler, SpringdotNETEventsExample">

    <!-- wired up to an event exposed on an instance -->

    <listener event="Click" method="HandleEvent">

        <ref object="source"/>

    </listener>

</object>

 

이 경우는 다른 두 개의 개체가 자신의 method 어트리뷰트에 HandleEvent 메서드를 명시적으로 사용하여 호출하며, event 어트리뷰트에 규정된 Click 이벤트가 발생하면 ref 엘리먼트로 참조되는 개체가 트리거된다

 

5.3.3.3. 정규 표현식 기반의 핸들러 메서드 컬렉션 등록

정규 표현식을 사용하면, 하나 이상의 이벤트 메서드를 묶어서 개체에 적용할 수 있다.

 

<object id="eventListener" type="SpringdotNETEventsExample.TestEventHandler, SpringdotNETEventsExample">

    <listener method="Handle.+">

        <ref object="source"/>

    </listener>

</object>

 

모든 eventListener 의 핸들러 메서드는 ‘Handle’ 로 시작하고 두 개의 파라미터 System.Object System.EventArgs 를 가지며, source 개체에 의해 모든 이벤트가 등록될 것이다.

이벤트의 트리거의 타입을 기반의 정규 표현식을 이용하면, 이벤트의 이름으로 핸들러 메서드를 필터할 수 있다.

 

<object id="eventListener" type="SpringdotNETEventsExample.TestEventHandler, SpringdotNETEventsExample">

    <!-- For the Click event, the HandleClick handler method will be invoked. -->

    <listener method="Handle${event}">

        <ref object="source"/>

    </listener>

</object>

 

5.3.3.4. 정규 표현식에 대응하는 이름을 가진 이벤트에 핸들러 메서드 등록

정규 표현식을 사용해 이벤트 이름을 필터링해서, 개체의 핸들러 메서드를 등록할 수 있다.

<object id="eventListener" type="SpringdotNETEventsExample.TestEventHandler, SpringdotNETEventsExample">

    <listener method="HandleEvent" event="Cl.+">

        <ref object="source"/>

    </listener>

</object>

 

이 예에서는 eventListener HandleEvent 핸들러 메서드는 ‘CI’  로 시작하는 이벤트 발생 시에 호출될 것이다.

 

5.3.4. depends-on 사용

대부분의 경우, 개체는 다른 개체에 설정된 프로퍼티를 통해 의존이 표현되며, 이를 위해 <ref> 엘리먼트를 사용한다. 간혹 개체간 의존의 간접적 연관을 ( 예를 들어 클래스의 정적 initializer 는 트리거된다.)  depends-on 어트리뷰트를 사용하여 표현한다. 아래의 예에서 depends-on 어트리뷰트로 하나의 개체와 의존을 표현했다.

 

<object id="objectOne" type="Examples.ExampleObject, ExamplesLibrary" depends-on="manager">

    <property name="manager" ref="manager"/>

</object>

<object id="manager" type="Examples.ManagerObject, ExamplesLibrary"/>

 

많은 개체와 의존을 갖는 것을 표현하려면, depends-on 어트리뷰트에 개체의 목록 이름을 콤마, 공백문자, 세미콜론 등의 유효한 구분자를 사용하여 값을 넣는다.

 

<object id="objectOne" type="Examples.ExampleObject, ExamplesLibrary" depends-on="manager,accountDao">

    <property name="manager" ref="manager" />

</object>

<object id="manager" type="Examples.ManagerObject, ExamplesLibrary" />

<object id="accountDao" type="Examples.AdoAccountDao, ExamplesLibrary" />

 

Note

depends-on 어트리뷰트와 프로퍼티는 초기화 단계 의존을 규정하며, 해당 소멸 단계 의존 규정시에 사용된다. ( singleton 개체만 ) depends-on 어트리뷰트에서 정의되는 연관되는 개체는, 개체 자체가 소멸된 후에 의존 개체가 소멸된다. 따라서 셧다운 명령을 제어할 수 있게 된다.

 

5.3.5. 늦게 인스턴싱 되는 개체

IApplicationContext 구현의 기본 동작은 모든 singleton 개체를 시작시 미리 인스턴싱하는 것이다. 미리 인스턴싱 하는 것은 IApplicationContext( 초기화 프로세스의 한 부분으로서 ) 모든 singleton 개체를 부지런히 만들고 구성한다는 것이다. 이것은 구성상의 에러나 환경이 즉시 발견되기 때문에 일반적인 경우에 좋은 것이다.

그러나 이런 동작을 원하지 않을 때가 있다. IApplicationContext를 사용할 때 singleton 개체를 미리 인스턴스화 하고 싶지 않다면, 개체 정의에 초기화를 늦게 사용하도록 표시하여 선택적으로 제어할 수 있다. 늦게 초기화 되는 개체는, 시작시 인스턴스가 생성될 때나 처음 요청되는 것인지에 상관없이 IoC 컨테이너에 지시할 수 있다.

XML 로 개체를 구성할 때, 늦은 로딩은 <object> 엘리먼트의 lazy-init 어트리뷰트로 제어한다. 예를 들어

 

<object id="lazy" type="MyCompany.ExpensiveToCreateObject, MyApp" lazy-init="true"/>

<object name="not.lazy" type="MyCompany.AnotherObject, MyApp"/>

 

구성을 사용하면, IApplicationContext은 개체 이름에 lazy 가 들어있으면 시작할 때, 미리 인스턴스화 하지 않는다. 반면 not.lazy 개체는 미리 인스턴스화 될 것이다.

늦은 초기화를 이해하는 한가지 방법은, 늦은 초기화로 설정된 개체의 정의를 통해서이다. 늦은 초기화 개체는 늦은 초기화가 아닌 singleton 개체의 의존을 가진다면, IApplicationContext 는 이 singleton 개체를 미리 초기화 할 때, singleton 개체의 의존이 모두 늦은 초기화 개체인지 만족해야, 미리 초기화를 할 것이다. IoC 컨테이너가 시작 시, 명시적으로 늦은 초기화로 구성된 개체 중 하나를 생성함을 혼동하지 말자. 이는 늦은 초기화 개체가 비-늦은 초기화된 singleton 개체에 삽입되는 것을 의미한다.

컨테이너 레벨의 늦은 초기화 제어는 <objects/> 엘리먼트의 default-lazy-init 어트리뷰트를 사용한다.

 

<objects default-lazy-init="true">

    <!-- no objects will be pre-instantiated... -->

</objects>




[출처] Spring.NET Framework 가이드 문서

[업데이트]
1차 : 2009-09-23 11:33
저작자 표시 비영리 변경 금지
Posted by kunami

최근에 달린 댓글

최근에 받은 트랙백

글 보관함