开发者

Prism View Injection Presenter and Garbage Collection

In Microsoft's view injection sample/article they have the code like the following:

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

here Presenter is resolved which contains the public property of type IEmployeesView and thats used for injecting the view to the region. The benefit of resolving the presenter is that it gets automatically tied to the view (by taking it in constructor (via unity)). However don't you think the Presenter is prone to garbage collection because nothing has reference to presenter after the scope of initialize method ends?

View/ViewModel obviously won't have reference to presenter unless VM/View has an event which is subscribed by presenter. We can go into an inconsistent state in which the view is active but the presenter is garbage collected.

To prevent garbage collection of presenter probably we'll ne开发者_高级运维ed a KeepAlive property in ViewModel that just holds the reference to presenter for preventing its GC but that sounds hacky to me. What do you do or would do in this situation?

Please note that in a situation where there will be multiple instances of the view, registering the presenter with ContainerControlledLifetimeManager is not feasible. Also if the mode of communication for presenter (with view) is via commands and the commands happen to be DelegateCommands of prism then they will only keep weak reference to the presenter so that won't serve the purpose either.


This is a complicated question about lifetime. In this example in the Prism documentation, the implementation of the 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);
        }

This ties the lifetime of the EmployeesPresenter to the lifetime of the IEmployeesListPresenter. It is registered with the container like this:

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

Not staticly or ContainerControlledLifetime, either. Now we have to look at the implementation of EmployeesListPresenter. Here is its constructor:

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

Now we see that the EmployeesListPresenter is tied up in the lifetime of the IEmployeesListView.

So, the lifetime of the EmployeesPresenter is the same as the EmployeesListView, which will be essentially as long as it is in the control tree.

This is a pretty confusing sample. You will find that the Prism 4 samples are much more straightforward... I would recommend looking at them and possibly upgrading to Prism 4 if you have a choice.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜