2010-12-09 32 views
0

Dans l'échantillon injection de vue de Microsoft/article qu'ils ont le code comme ce qui suit:Prism Voir Présentateur Injection et Garbage Collection

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

ici Presenter est résolu qui contient la propriété publique de type IEmployeesView et c'est utilisé pour injecter la vue à la région. L'avantage de résoudre le présentateur est qu'il est automatiquement lié à la vue (en le prenant dans le constructeur (via l'unité)). Cependant, ne pensez-vous pas que le Presenter est sujet à la garbage collection parce que rien ne fait référence au présentateur après la fin de la portée de la méthode initialize?

View/ViewModel ne fera évidemment référence au présentateur que si VM/View a un événement souscrit par le présentateur. Nous pouvons entrer dans un état incohérent dans lequel la vue est active mais le présentateur est collecté.

Pour éviter la récupération de mémoire du présentateur, nous aurons probablement besoin d'une propriété KeepAlive dans ViewModel qui contient simplement la référence au présentateur pour empêcher son GC, mais cela me semble bizarre. Que faites-vous ou feriez-vous dans cette situation?

Veuillez noter que dans une situation où il y aura plusieurs instances de la vue, l'enregistrement du présentateur avec ContainerControlledLifetimeManager n'est pas réalisable. Aussi, si le mode de communication pour le présentateur (avec vue) est via des commandes et que les commandes sont des Commandes de prisme, alors elles ne garderont qu'une faible référence au présentateur, ce qui ne servira pas non plus le but.

+0

Le * conteneur * ne contient-il pas la référence au Presenter, c'est la raison pour laquelle vous l'utilisez? Le code affiché consiste simplement à saisir une référence à ce présentateur et à coller sa vue dans une région ... –

+0

À quoi faites-vous référence en tant que conteneur? –

+0

Le conteneur est le conteneur UnityContainer. Généralement, un Resolve <> lui-même n'ajoutera l'objet au conteneur que si vous enregistrez le type en tant que ContainerControlledLifetimeManager ou PerInstanceLifetimeManager (que vous pouvez écrire) qui l'ajoutera au conteneur. – aqwert

Répondre

2

Ceci est une question compliquée sur la durée de vie. Dans cet exemple, dans la documentation Prism, la mise en œuvre du 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); 
     } 

Cela correspond à la durée de vie du EmployeesPresenter à la durée de vie du IEmployeesListPresenter. Il est inscrit sur le récipient comme celui-ci:

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

Non staticly ou ContainerControlledLifetime, que ce soit. Maintenant, nous devons regarder l'implémentation de EmployeesListPresenter. Voici son constructeur:

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(); 
     } 

Maintenant, nous voyons que le EmployeesListPresenter est lié à la durée de vie du IEmployeesListView. Ainsi, la durée de vie de EmployeesPresenter est la même que celle de EmployeesListView, qui sera essentiellement aussi longue que dans l'arborescence de contrôle.

Ceci est un échantillon assez confus. Vous constaterez que les échantillons de Prism 4 sont beaucoup plus simples ... Je vous recommande de les regarder et éventuellement de passer à Prism 4 si vous avez le choix.

+0

C'est vrai que la durée de vie est implicitement gérée dans certaines situations parce que le présentateur a branché sur un événement publié par vue, mais ce n'est pas quelque chose qui peut être systématiquement suivi comme un modèle dans une application. La vraie question est de savoir quelle stratégie de gestion de la vie tout le monde utilise dans une situation comme celle-ci? –

+1

@ Hasan Khan: Dans mon cas, je n'utilise pas MVP ... Je pense que cela complique trop les choses. J'utilise MVVM et permet aux ViewModels de communiquer directement via EventAggregator ou un autre mécanisme. Je ne pense pas que l'apport d'un tiers ajoute beaucoup plus que complication. Je pense que vous verrez également ce changement dans les échantillons de Prism 4. –

+0

@Anderson Imes - Si vous avez une chance, s'il vous plaît jeter un oeil à ma question ici. http://stackoverflow.com/questions/15049256/wpf-prism-4-1-garbage-collection-memory-issues J'utilise aussi MVVM mais je n'arrive pas à comprendre ce que j'ai une fuite de mémoire dans ma très simple application de démonstration Prism. –