2010-12-09 7 views
0

있습니다프리즘보기가 다음과 같은 코드를 마이크로 소프트의보기 주입 샘플/기사에서는 사출 발표자 및 쓰레기 수거

public void Initialize() 
{ 
    this.RegisterViewsAndServices(); 
    EmployeesPresenter presenter = this.container.Resolve<EmployeesPresenter>(); 
    IRegion mainRegion = this.regionManager.Regions[RegionNames.MainRegion]; 
    mainRegion.Add(presenter.View); 
} 

http://msdn.microsoft.com/en-us/library/dd458920.aspx

여기 발표자 유형 IEmployeesView의 공공 재산을 포함하는 해결되고 그 지역에보기를 주입하는데 사용되는 것들. 발표자를 해결하는 이점은보기에 자동으로 연결된다는 것입니다 (단결을 통해 생성자에서 가져옴). 그러나 초기화 메서드의 범위가 끝난 후에 발표자에 대한 참조가 없으므로 발표자가 가비지 수집을하는 경향이 있다고 생각하지 않습니까?

VM/View에 발표자가 구독하는 이벤트가 없다면 ViewModel은 분명히 발표자를 언급하지 않습니다. 우리는보기가 활성화되어 있지만 발표자가 가비지 수집되는 일관성없는 상태로 갈 수 있습니다.

발표자의 가비지 수집을 방지하려면 ViewModel에서 GC를 막기 위해 발표자에 대한 참조를 보유하고 있지만 해커처럼 들리 네요. 이 상황에서 당신은 무엇을합니까?

보기의 인스턴스가 여러 개인 경우 Presenter를 ContainerControlledLifetimeManager에 등록하는 것이 적합하지 않습니다. 또한 프리젠터 (보기 포함)에 대한 통신 모드가 명령을 통해 이루어지고 명령이 프리즘의 DelegateCommands 일 경우 프리젠 테이션에 대한 약한 참조 만 유지하므로 목적을 달성하지 못합니다.

+0

* 컨테이너 *는 발표자에 대한 참조를 보유하고 있지 않으므로 그 이유는 무엇입니까? 표시된 코드는 해당 Presenter에 대한 참조를 가져 와서 해당보기를 영역으로 고정하는 것입니다. –

+0

컨테이너로 무엇을 언급하고 있습니까? –

+0

컨테이너가 UnityContainer입니다. 일반적으로 Resolve <> 자체는 컨테이너에 컨테이너를 추가하는 ContainerControlledLifetimeManager 또는 PerInstanceLifetimeManager (사용자가 작성할 수 있음)로 유형을 등록하지 않는 한 컨테이너에 객체를 추가하지 않습니다. – aqwert

답변

2

이것은 수명에 대한 복잡한 질문입니다. 프리즘 문서에서이 예에서, EmployeesPresenter hooks up to an event on the EmployeesListPresenter의 구현 :

public EmployeesPresenter(
      IEmployeesView view, 
      IEmployeesListPresenter listPresenter, 
      IEmployeesController employeeController) 
     { 
      this.View = view; 
      this.listPresenter = listPresenter; 
      this.listPresenter.EmployeeSelected += new EventHandler<DataEventArgs<BusinessEntities.Employee>>(this.OnEmployeeSelected); 
      this.employeeController = employeeController; 

      View.SetHeader(listPresenter.View); 
     } 

이것은 IEmployeesListPresenter의 수명에 EmployeesPresenter의 수명을 묶어. 다음과 같이 컨테이너에 등록됩니다.

this.container.RegisterType<IEmployeesListPresenter, EmployeesListPresenter>(); 

staticly 또는 ContainerControlledLifetime 중 하나입니다. 이제 EmployeesListPresenter의 구현을 살펴보아야합니다.

public EmployeesListPresenter(IEmployeesListView view, 
      IEmployeeService employeeService) 
     { 
      this.View = view; 
      this.View.EmployeeSelected += delegate(object sender, DataEventArgs<BusinessEntities.Employee> e) 
      { 
       EmployeeSelected(sender, e); 
      }; 
      view.Model = employeeService.RetrieveEmployees(); 
     } 

지금 우리가 EmployeesListPresenter이 IEmployeesListView의 수명에 묶여 것을 볼 : 여기 생성자입니다.

따라서 EmployeesPresenter의 수명은 EmployeesListView와 동일합니다. 이는 본질적으로 제어 트리에있는 한 오래 유지됩니다.

이것은 매우 혼란스러운 샘플입니다. Prism 4 샘플이 훨씬 더 직관적이라는 것을 알게 될 것입니다 ... 선택이 있다면 Prism 4 샘플로 업그레이드하는 것이 좋습니다.

+0

발표자가보기에 의해 게시 된 일부 이벤트에 접속했기 때문에 일부 상황에서는 수명 시간이 암시 적으로 처리되지만 이는 응용 프로그램에서 일관되게 패턴을 따를 수있는 것이 아닙니다. 진정한 질문은 평생 관리 전략이 이런 상황에서 모든 사람들이 사용하는 것입니다. –

+1

@ 하산 칸 : 제 경우에는 MVP를 사용하지 않습니다 ... 너무 복잡하게 생각합니다. MVVM을 사용하고 ViewModel이 EventAggregator 또는 다른 메커니즘을 통해 직접 통신 할 수 있도록합니다. 나는 제 3자를 데려 오는 것이 합병증 외에 많은 것을 추가한다고 생각하지 않는다. 나는 당신이 프리즘 4 샘플에서이 변화를 볼 것이라고 생각합니다. –

+0

@Anderson Imes - 기회가 생기면 여기 내 질문을보십시오. http://stackoverflow.com/questions/15049256/wpf-prism-4-1-garbage-collection-memory-issues MVVM을 사용하지만 아주 간단한 프리즘 데모 응용 프로그램에서 메모리 누수가 무엇인지 알아낼 수는 없습니다. –

관련 문제