감사합니다. 어떤 사람들은 이 방식에 부정적인 의견인 분들도 있었거든요. 하지만 이렇게 안하면 다른 mvvm 프레임워크를 많이 사용해야 될 듯 해서, 전 공식 지원이 아닌 프레임워크는 최대한 사용하지 말자라는 주의거든요. 설령 공식 지원이라도 가능하면 최대한 안쓰려는 주의라서 ㅎㅎ
여담이지만 저도 프레임워크를 지양하는 방식으로 오래 해오고 있습니다. 분명 거기서 오는 장점이 확실히 있는 것 같아요. 하지만 반대로 부작용도 생길 수도 있을 것 같습니다. 모든 상황에 다 들어맞는 방법론은 없기 때문에 다른 방식도 관심 있게 보시면 지금 만들고 계신 구조가 더 강력해질 것 같습니다.!!
그리고 @mincook 질문자님 구조에서 DI(IoC) 요소를 첨가하면 INavigation 처럼 필요에 따라 View 인터페이스를 다양하게 만들어 사용하면 더 재밌는 구조가 될 것 같네요.
개인적으로 Window 클래스에 INavigation 인터페이스를 확장하도록 하여 ViewModel에 참조를 전달하는 방식이 MVVM 구조에 위배된다고 생각하지 않습니다. ISP에도 부합 되고, 테스트 가능해 괜찮은 방식이라는 생각이 드네요.
다만, 좀더 느슨한 구조와 재사용성을 높이기 위해 몇가지 다른 방식들을 제안드려 봅니다.
첫번째는 바인딩을 이용한 방식입니다.
이 방식은 상태 기반으로 동작하기 때문에 상태 변화에 따른 콜백을 미리 등록하여 처리 가능하도록 구성해야 합니다.
두번째는 구성하시려는 INavigation과 비슷한 형태인데, View를 간접 참조하도록 별도의 인터페이스를 구성하는 방식입니다.
이 방식과 생각하신 INavigation과의 차이점이라면 View를 간접 참조하게 구성할 수 있고, 대상 뷰가 아닌 다른 뷰들도 참조할 수 있어 공통화된 코드 수행이 용이하고 SRP를 준수하여 코드 재사용성이 높다고 볼수 있습니다.
세번째는 Messenger를 활용한 이벤트 기반 처리 방식입니다.
ViewModel 이벤트를 발행하고, 이를 구독하고 있는 View에서 후 처리를 진행합니다.
대부분의 MVVM 프레임워크들은 Event Aggregator를 필수적으로 구현하고 있습니다.
그래서 아주 Common한 방식으로 이해해주셔도 될 것 같네요.
View와 ViewModel의 생명주기가 다른 경우 메모리 누수가 발생 될 위험이 있는데 대부분의 Messenger는 WeakReference 방식으로 참조를 관리하여 이 문제를 해결합니다.
이외에는 사용자 정의 EventTriggerAction, 사용자정의 Behavior 등이 있습니다.