2009-10-19 7 views
1

위로 또는 아래로?Inversion of Control (Dependency Inversion) 시스템의 이벤트는 어떤 방식으로 진행됩니까?

저는 매우 시각적 인 사람입니다. 내 응용 프로그램을 계층 구조로 생각하고 있는데, 위쪽은 루트이고 아래쪽은 리프입니다.

IoC 컨테이너가 포함 된 개체의 책임/기능을 모르고 있다는 것도 이해하고 있습니다. 대신, 포함 된 객체는 추상화 된 인터페이스를 통해 컨테이너 (즉, "컨텍스트")에 대해 알고 있습니다.

UP : 포함 된 개체의 인식이되도록 (? 비 IOC의 방법) 는 내 이벤트는 부모에 체인의 책임 패턴을 통해 내 계층 구조 위쪽으로 거품의 바닥에서 파견해야 그들의 용기? 예 : 내 GUI의 버튼은 청취 컨테이너 창이 닫히면 응답하는 창이 걸린 인 CLICKED 이벤트를 전달합니다.

DOWN : (IOC의 방법?) 내 이벤트가 컨테이너에 의해 내 계층 구조의 상단에서 파견 컨테이너가 그 내용을 모르고이되도록 용기에 직접 가입 한 포함 된 청취자에 도달해야 하는가? 예 : 컨테이너 윈도우는 자신을 닫음으로써 응답하는 포함 된 버튼 객체에 의해 직접 수신 된 인 CLOSED 이벤트를 전달한 다음 자신을 닫음으로써 창을 닫습니다.

'Up'은 자연스러운 것처럼 보이지만 IoC에는 컨테이너에 포함 된 개체의 동작을 인식하지 못하기 때문에 이벤트에 응답하고 싶지 않습니다.

시스템의 거의 모든 부분에서 이벤트를 수신 할 수 있음을 알고 있지만 IOC 참가자들 간의 기본적인 관계를 이해하고 싶습니다. 그래서 제대로 구성 할 수 있습니다.. 나는 사람들이 일반적으로 구조적 관계, 의존성 등에 관계없이 그들의 프로그램에 관한 이벤트를 분산시키지 않는다고 가정하고있다.

내 질문은 IoC 시스템의 책임 배치에서 발생한다. 컨테이너에 의존적 인 객체에 대한 서비스를 제공하는 컨테이너의 책임 (비 IoC 패러다임을 반전 시킴 - 따라서 "Dependency Inversion"과 동의어). 이것은 IoC의 매우 중요하고 기본적인 구성 요소 인 것 같습니다. 책임의 변화입니다. 나는 다른 객체에 의존하는 예제가 될 수 있도록 객체의 함수를 호출하거나 이벤트를 청취하는 것을 고려한다. 객체가 다른 객체를 기반으로하는 자체 동작을 정의 할 때, 한 객체가 다른 객체를 알고 있고 다른 객체가 알고있는 것이 있기 때문에 종속 객체라고 부릅니다. 다른 객체의 컨텍스트 내에서 자체를 정의했습니다. 알 수 있듯이 IoC는 포함 된 객체가 컨테이너에 종속되도록 설정되므로 컨테이너에 대한 모든 것을 아는 것은 포함 된 객체의 책임이어야합니다. 그리고 그것은 포함 된 객체에 대해 알기위한 컨테이너의 책임이되어서는 안됩니다. 그래서, CONTAINER가 포함 된 객체의 이벤트를 듣고있는 것은 저에게 그 내용에 대해 뭔가를 알고 있기 때문에 책임의 잘못 배치 된 것처럼 생각됩니다.

이 질문은 종속성 '주입'과 '반전'이 다른 것을 학습 한 후에 다시 설명합니다. 이전 질문은 here입니다.

답변

4

간결하게하기 위해 컨테이너에 포함 된 개체를 "클라이언트 개체"또는 "클라이언트"라고합니다 ...

이벤트는 컨테이너와 클라이언트간에 원하지 않는 종속성을 유발하지 않으면 서 양방향으로 합법적으로 흐를 수 있습니다. 실제로 컨테이너가 클라이언트의 이벤트를 수신하도록 허용하는 것은 이러한 종속성을 최소화하는 좋은 방법입니다. 이들은 컨테이너가 클라이언트와 실제로 의사 소통을하는 동안 클라이언트가 실제로 무엇인지 모를 수 있도록 정확한 연결을위한 경로를 제공합니다. 문제가되는 이벤트가 클라이언트가 아니라 컨테이너에 의해 정의되는 한.

클라이언트 개체가 컨테이너에서 사용되는 이벤트를 실행한다는 생각이 대부분입니다. 이러한 이벤트가 클라이언트 오브젝트에 의해 정의 된 경우 이것은 문제가됩니다. 이것은 분명히 컨테이너로부터의 클라이언트 객체에 대한 강한 의존성을 생성 할 것이다; 컨테이너는 클라이언트 정의 이벤트에 대해 알아야하며이를 위해 특별히 코딩되어야합니다. 이것은 IoC의 주요 아이디어를 무너 뜨릴 것이다. 그러나 이러한 이벤트가 컨테이너에 의해 정의되는 경우에는 걱정할 필요가 없습니다. 실제로 컨테이너를 클라이언트 객체와 느슨하게 결합하는 것이 가장 좋습니다. 고객은 컨테이너에서 소비하기 위해 해당 이벤트를 실행할 수 있지만 이벤트를 정의하지는 않습니다. 컨테이너가 정의한대로 컨테이너가 수신 대기하는 일련의 이벤트 만 발생시킬 수 있습니다. (물론 그들은 다른 목적을 위해 다른 사건을 일으킬 수 있지만, 용기는 알지도 모르게 될 것이다).

예를 들어, 컨테이너가 UI의 작은 콘텐츠 상자 인 "보기"를 표시하고 인쇄 할 수있는 기능을 제공한다고 생각하십시오 (언급 한 환경에서 사용자가 게시물에서 암시 한 환경 인 것 같습니다. 매우 많은 GUI 예제 - 그러나 이러한 개념은 GUI와 관련이없는 것 외에 적용됩니다. 컨테이너는 Print라는 이벤트를 인쇄합니다.이 이벤트는 인쇄 할 항목에 대한 매개 변수를 취합니다 (IP 인쇄 가능 인터페이스에 대한 참조 일 수도 있습니다. 인쇄 할 원시 데이터는 IoC로 달성하려는 작업에 따라 달라질 수 있음). 컨테이너 내부에서 실행중인 클라이언트 개체는 클라이언트 개체의 단추 중 하나를 누를 때 Print 이벤트를 발생시킬 수 있습니다. 그런 다음 컨테이너는 해당 이벤트를 수신하고 클라이언트 오브젝트를 대신하여 인쇄를 처리합니다. 또는 클라이언트 객체는 컨테이너가 수신하는 "CloseMe"이벤트를 실행할 수 있으며, 응답시 사용자를 묻는 것을 포함하여 다른 처리와 함께 이벤트를 발생시킨 클라이언트 객체를 파기합니다.

반대로 컨테이너는 클라이언트 개체가 필요한 이벤트가 발생하면 이벤트를 발생시킬 수 있습니다. 다시 말하지만 컨테이너에 대해서만 정의됩니다. 그러나 클라이언트 객체는 클라이언트 객체에 가입 할 수 있습니다. 이전 예제에서 컨테이너는 "Your document is done!"이라는 자체 UI 내에 메시지를 표시하기 위해 클라이언트 객체가 사용할 수있는 PrintFinished 이벤트를 노출 할 수 있습니다. 컨테이너는 ApplicationClosing 메시지를 발생시켜 모든 클라이언트 객체가 컨테이너가 완전히 닫히기 전에 보유하고있는 원시 리소스를 해체 할 수 있습니다. 이것들은 단지 어리석은 단순한 예일뿐입니다.

요약하자면, 합법적 일뿐만 아니라 이벤트가 컨테이너에서 클라이언트로 그리고 클라이언트에서 컨테이너로 이동하는 데 매우 유용하다고 생각합니다. "위로"또는 "아래로"와 아무런 관련이없는 핵심 사항은 누가 그러한 이벤트를 정의하는지입니다. 컨테이너는 모두 개로 정의됩니다.

+0

이것은 진정으로 최고 품질의 답변입니다. 그 위대함에 감사드립니다. 감사 :) – Pup

1

컨테이너는 구성 요소 또는 작동 방식을 알지 못합니다. 컨테이너의 책임은 일반적으로 통신 의존성이 아니라 인스턴스화 종속성의 영역입니다. 컨테이너는 일반화 된 팩토리 여야합니다.

왜 구조 그래프! = 통신 그래프입니까? 팩터가 컨테이너로서 객체 그래프의 루트이지만, 이벤트에 응답하거나 퍼블리싱하는 컨테이너는 의미가 없다는 것을 깨달았습니다.

그럼 당신이 원하는 것은 이벤트를 관리하는 사람입니다.에 대해 이벤트를 알고 있으며 브로커의 인스턴스를 이해할 수있는 전문 구성 요소입니다. 일반화 된 이벤트 브로커가 필요합니다. 이벤트 라우터.

많은 구현을 찾을 수 있습니다. Cab의 EventBroker, Prism의 이벤트 수집기 또는 내가 좋아하는 EventHub 등. 이 마지막 것은 Kent, a very cool guy에 의해 Jeremy Miller와 Glenn Block과 광범위하게 Cab과 일하는 경험의 절정입니다.

컨테이너를 사용하는 경우 종속성 주입 및 제어 반전에 대해 잘 알고있을 것입니다. 이벤트를 게시해야하는 사람은 IEventHub을 삽입하고 강력한 형식의 제목 클래스를 사용하여 게시를 호출합니다. 이벤트에 가입해야하는 사람은 또한 IEventHub을 삽입하고 강력하게 형식화 된 ISubscriber 인터페이스를 구현합니다. 기본적으로 강력한 형식의 Receive 메서드를 제공합니다. 그게 전부 야.

이제 이벤트는 [비즈니스 요구 사항에 따라] 어떤 방식 으로든 여행 할 수 있습니다.

관련 문제