Презентатор для инъекций с видом на призму и сборщик мусора - PullRequest
0 голосов
/ 09 декабря 2010

В образце / статье Microsoft для инъекций они имеют следующий код:

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

здесь разрешается Presenter, который содержит открытое свойство типа IEmployeesView и используется для внедрения представления в регион. Преимущество разрешения презентатора заключается в том, что он автоматически привязывается к представлению (принимая его в конструкторе (посредством единства)). Однако не думаете ли вы, что Presenter склонен к сборке мусора, потому что ничто не имеет ссылки на Presenter после окончания действия метода initialize?

View / ViewModel, очевидно, не будет иметь ссылки на докладчика, если VM / View не имеет события, подписанного докладчиком. Мы можем перейти в несовместимое состояние, в котором представление активно, но ведущий удален.

Чтобы предотвратить сборку мусора презентатора, вероятно, нам понадобится свойство KeepAlive во ViewModel, которое просто содержит ссылку на презентатор для предотвращения его GC, но это звучит для меня хакерски. Что вы делаете или сделаете в этой ситуации?

Обратите внимание, что в ситуации, когда будет несколько экземпляров представления, зарегистрировать докладчика с помощью ContainerControlledLifetimeManager невозможно. Кроме того, если режим связи для докладчика (с представлением) осуществляется с помощью команд, а команды, как оказалось, являются DelegateCommands призмы, то они будут хранить только слабую ссылку на докладчика, так что это также не будет служить цели.

1 Ответ

2 голосов
/ 13 декабря 2010

Это сложный вопрос о жизни. В этом примере в документации Prism реализация EmployeesPresenter подключается к событию в 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);
        }

Это связывает время жизни EmployeesPresenter со временем жизни IEmployeesListPresenter. Он регистрируется в контейнере следующим образом:

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

Не статично или не 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, если у вас есть выбор.

...