NotifyIcon
및 동적으로 채워진 ContextMenuStrip
으로 구성된 UI로 WinForms 응용 프로그램을 구축하고 있습니다. 응용 프로그램을 함께 보관할 수있는 MainForm
이 있지만 표시되지는 않습니다.IoC : 이벤트 처리기에 대한 종속성 확보
가능한 한 솔직하게 (객체 그래프를 처리하기 위해 Autofac을 사용하여) 이것을 빌드하고 O 부분과도 잘 어울리는 내 성공에 매우 만족합니다. 현재 구현중인 확장 기능으로 인해 디자인에서 결함을 발견했으며 조금 변형 할 필요가 있습니다. 나는 내가 갈 필요가있는 방법을 알고 있지만 의존성을 정확하게 정의하는 방법에 대해서는 약간 불분명하다고 생각한다.
위에서 언급했듯이 메뉴는 응용 프로그램을 시작한 후에 부분적으로 동적으로 채워집니다. 이를 위해, I는 IToolStripPopulator
인터페이스 정의 : 이것의 구현은 MainForm
에 주입
public interface IToolStripPopulator
{
System.Windows.Forms.ToolStrip PopulateToolStrip(System.Windows.Forms.ToolStrip toolstrip, EventHandler itemclick);
}
을하고 Load()
방법은 ContextMenuStrip
폼에 정의 PopulateToolStrip()
핸들러를 호출한다. populator의 종속성은 메뉴 항목에 사용할 데이터를 가져 오는 것과 관련이 있습니다.
이 추상화는 몇 가지 진화 단계를 통해 잘 수행되었지만 둘 이상의 이벤트 핸들러가 필요한 경우 더 이상 충분하지 않습니다. 왜냐하면 양식이 그것과 전혀 관련되어서는 안되기 때문에 하나의 IToolStripPopulator
인터페이스 뒤에 아직도 숨겨져있는 메뉴 항목의 여러 그룹을 생성하기 때문입니다. 좀 더 구체적인 뭔가에 IToolStripPopulator
인터페이스 *를 이름 대신에 주입 그 PopulateToolStrip()
의 메소드 EventHandler
매개 변수를 사용하지 않는 새로운 하나를 생성 - 내가 말했듯이
, 나는 내가 좋아하는 일반적인 구조가되어야 하는지를 알고 있다고 생각 객체 (구현 등에서 요구되는 핸들러의 수에 관해 훨씬 더 많은 유연성을 허용한다). 이런 식으로 나의 "제일"IToolStripPopulator
은 매우 쉽게 특정 수의 어댑터가 될 수 있습니다.
이제 내가 명확하지 않은 것은 EventHandler 종속성을 해결해야하는 방법입니다. 나는 핸들러가 모두 MainForm
에 정의되어야한다고 생각한다. 메뉴 이벤트에 적절하게 반응하는 데 필요한 다른 모든 의존성을 가지기 때문이다. 또한 메뉴를 "소유"한다. 즉, IToolStripPopulator
개체가 결국 MainForm에 삽입되면 Lazy<T>
을 사용하여 MainForm
개체 자체에 대한 종속성을 가져와야합니다.
public interface IClickHandlerSource
{
EventHandler GetClickHandler();
}
이 내 MainForm
에 의해 구현되고, 내 특정 IToolStripPopulator
구현 Lazy<IClickHandlerSource>
에 종속성을했다 :
내 첫번째 생각은 IClickHandlerSource
인터페이스를 정의했다. 이 방법이 효과가있는 반면 융통성이 없습니다. 잠재적으로 증가하는 핸들러 (MainForm
클래스의 OCP를 심각하게 위반하는)에 대해 별도의 인터페이스를 정의하거나 IClickHandlerSource
(주로 ISP 침해)까지 확장해야합니다. 이벤트 핸들러에 대한 의존성을 직접적으로 고려하는 것은 소비자 측에서 좋은 아이디어처럼 보일 수 있지만, 게으른 인스턴스 (또는 이와 유사한 것)의 속성을 통해 생성자를 개별적으로 연결하는 것은 가능하다면 꽤 지저분 해 보입니다.
내 가장 좋은 방법은 현재이 될 것으로 보인다 :
public interface IEventHandlerSource
{
EventHandler Get(EventHandlerType type);
}
인터페이스는 여전히 MainForm
에 의해 구현하고 게으른 싱글로 주입 될 것이며, EventHandlerType
내가 필요로하는 다른 유형의 사용자 정의 열거 될 것이다. 이것은 여전히 OCP와 거의 일치하지는 않지만 합리적으로 유연합니다. EventHandlerType
은 새 이벤트 처리기 자체 및 새롭게 작성된 IToolStripPopulator
의 추가 구현 외에도 해상도 논리가 MainForm
인 것과 같이 새로운 유형의 이벤트 처리기마다 분명히 변경됩니다.
아니면 .... (유일한 목적으로) MainForm
에 정의 된 특정 핸들러에 EventHandlerType
옵션 Lazy<MainForm>
에 종속 취하고 해결 IEventHandlerSource
별도 구현?
실제로 이벤트 핸들러를 MainForm
에서 꺼내는 방법을 생각하려고합니다.하지만 지금 당장은 그렇게 생각할 수 없습니다.
다른 이벤트 핸들러에서 가장 느슨한 커플 링과 가장 세련된 해상도를 제공하는 가장 좋은 옵션은 무엇입니까?
[* 네, 아마 정말 OCP 준수하기 만 이름을 떠난해야하지만 더 나은 그런 식으로 보았다.]
나는 귀하의 질문에 여러 번 읽기를 구현하지만 몇 가지 정보를 누락. 더 많은 코드를 보여줄 수 있습니까? 예를 들어,'IEventHandlerSource'의 소비자는 어떻게 생겼고'IEventHandlerSource'의 구현은 어떻게 보이며, 어떻게 등록되어 있습니까? – Steven