2012-12-12 2 views
7

인터넷에서 보았던 WPF MVVM 응용 프로그램의 예 VM은 외부 라이브러리의 "이전"이벤트를 사용하는 서비스 계층과 상호 작용하는 계층이거나, HTTP를 사용하여 웹 또는 뭐든간에. 그러나 모든 M, V, VM, 서비스 및 기타 부품을 직접 제작하면 어떻게됩니까? 서비스 계층과 뷰 모델 계층 간의 상호 작용을 올바르게 구축하는 방법은 무엇입니까? ObservableCollection<OrderModel>을 서비스에 넣고 뷰의 뷰 모델에서 그대로 반환 할 수 있습니까? 그렇지 않은 경우 나쁜 방법으로 간주되고 더 좋은 대안이 있습니까?WPF MVVM 응용 프로그램 서비스 계층의 ObservableCollection

답변

6

물론이 작업을 수행 할 수 있습니다. 이러한 일을하는 주된 이유는 여러 WPF 응용 프로그램에서 중복을 줄이는 것입니다.

그러나 서비스 계층/데이터 계층 구현에 따라 일부 시나리오에서 발생할 수있는 문제는 데이터베이스 연결을 사용하는 장기 실행 서비스입니다. ObservableCollections는 서비스 계층이 애플리케이션에 의해 변경된 사항을 데이터 저장소에 자동으로 동기화시키는 관점에서 유혹하고 있습니다. 그러나 데이터 자체에서 발생하는 변경 사항을 전달하려는 경우 (즉, 데이터를 작성/수정하는 다른 프로세스에 대한 응답으로) 복잡해집니다.

서비스 계층은 더 이상 참조의 유일한 소유자가 아니기 때문에 (즉, 대규모 변경의 경우) 인스턴스를 대체 할 수 없습니다.하지만 가능한 경우에도 인스턴스를 대체하는 것은 UI가 컬렉션에 대해 갖는 모든 바인딩을 끊습니다.

그래서 하나의 인스턴스를 최신 상태로 유지하려고 노력합니다. 서비스가 데이터베이스에 바인딩 된 경우 서비스 내에서 장기 실행 모니터링 프로세스의 일부 양식을 작성하지 않는 한 ObservableCollection을 최신 상태로 유지하는 유일한 방법은 데이터베이스 연결/컨텍스트 (Linq to Sql 또는 EF의 경우)가 열려 있어야합니다. 그렇지 않으면 관련 오브젝트 등이 검색 가능하지 않기 때문입니다 (모든 오브젝트를 강제로 한 번에 읽지 않는 한 - 확장 가능하지 않음).

좋아, 그래서 당신을 위해 연결을 관리 할 수있는 관리 레이어의 몇 가지 양식을 작성할 수 있습니다 -하지만 피할 수없는 폴링, 또는 아마도 당신이 사용하는 SQL Server 알림 이외에, 나는 코드가 상당히 복잡해 질 수 있다고 생각 .

그렇긴하지만 그것은 정말로 의존합니다. 특정 문제는 조심해야 할 것이지만, 그러한 것들이 단순히 중요하지 않은 아키텍처와 환경을 가지고있을 수도 있습니다.

내 조언, 시도하고 싶다면 - 계속하십시오. 나를 위해서? 생각해 봤는데 - 일부 도메인 모델에 INotifyPropertyChanged를 추가하는 것 외에 응용 프로그램 자체의 VM이 있다는 생각을 고수합니다. 여러 응용 프로그램이 동일한 VM을 공유 할 수도 있지만 서비스 계층 자체에는 포함되지 않습니다.

서비스 레이어는 데이터 및 비즈니스 로직에 대한 액세스를 일반적으로 원샷 방식으로 제공합니다. VM 패턴의 클래스는 수명이 훨씬 오래갑니다. 장기 실행 서비스 레이어를 코딩하려고 시도하는 것은 악명이 높습니다. 특히 미래의 모든 응용 프로그램에서 발생할 수있는 모든 문제를 해결하려고 시도하는 경우 매우 그렇습니다. 필연적으로 단일 응용 프로그램에 대해서만 서비스 계층 내에서 코딩 서비스 또는 VM 유형을 종료하게됩니다.이 경우 해당 응용 프로그램의 코드베이스에도 적용될 수 있습니다.

0

나는 여러 가지 이유로 그렇게하지 않을 것이다. 그들은 여기에 문서화되어 있습니다 : Common mistakes with an observable collection

저자는 사람들이 서비스 계층에서 사용하는 것을 포함하여 몇 가지 실수를 저질렀습니다.

+0

이 기사에서는 "모델에서 사용"섹션에서 모델에서 OC를 사용하는 것이 좋지 않다고 말합니다. 그러나 모델을 그대로 변환없이보기로 제공하면 많은 예제를 보았습니다. 권장 사항 중 하나는 "모델에서 INotifyPropertyChanged를 구현하면 사용하고 그렇지 않으면 변환"입니다. 따라서 모델에서 관찰 가능한 컬렉션을 사용하는 것은 모든 사람이 나쁜 습관으로 생각하지 않습니다 ... 어쨌든, 질문은 : 대체 방법이 무엇인지, 올바른 방법입니까? – Athari

+0

대체 방법 (올바른 방법)은 IEnumerable을 사용하는 것입니다. @PeteH가 제안한 것처럼 OC를 가능한 한 멀리, 즉 ViewModel에서 사용하도록하십시오. 또한 ViewModels의 ObservableCollection을 OnCollectionChanged 등의 구독으로 속성으로 표시하는 CollectionViewModel 클래스를 작성하십시오. – Heliac

2

ObservableCollection을 "관찰 가능한"측면과 관련이있는 지점에서만 사용해야합니다. 일반적으로 VM이 뭔가를 V에 노출시키는 지점입니다. 스택 (예 : M)을 내려 가면 목록 및 컬렉션과 같은보다 일반적인 것들을 사용하고 싶은 유혹을받을 수 있습니다 (특별히 그렇지 않은 경우 제외). 어떤 경우에도 이전 IEnumerable을 기반으로 ObservableCollection을 만드는 데 VM이 충분히 쉽습니다.

특히 ObservableCollection의 System.Collections 네임 스페이스에있는 배치가 Microsoft가 특별히 특수 클래스 (물론 wpf에만 해당되는 것은 아닙니다)라고 생각하지 않는 것처럼 보일 수도 있습니다.

+0

"전통적인"목록 및 열거 형의 문제는 여전히 뭔가가있을 때 viewmodel을 통해 뷰를 업데이트해야한다는 것입니다. 목록에 추가; 따라서 뷰 모델은 서비스에 의해 새 항목에 대한 알림을 받아야합니다. 이벤트를 추가하면 관찰 가능한 컬렉션의 나쁜 (아마도 버그가있는) 구현처럼 보일 것입니다 ... – Athari

+0

@Athari 내가 어디에서 왔는지 확인할 수 있습니다. 자신의 ObservableCollection을 구현하는 것이 확실하지 않습니다. 스택을 더 내려다 보면서 서비스가 어떻게 상황이 변경되었음을 알 수 있습니까? – PeteH

+0

@Athari - 그건 내가하는 일입니다. 프로그래밍 방식으로 새 항목을 추가하면 (예 : DataGrid 새 행을 사용하지 않고 엔티티 추가), 리포지토리의 Create 메서드에서 가져 오는 OnEntityAdded 이벤트가 발생합니다. ** OnEntityAdded (새 ModelEntityAddedEventArgs (엔터티)) ** . 보시다시피, 엔티티는 이벤트 인수로 전달됩니다. 내 서비스 계층은이 이벤트를 구독합니다. – Heliac

관련 문제