2013-04-08 2 views
3

У меня очень простой WinForms POC, использующий Autofac и шаблон MVP. В этом POC я открываю дочернюю форму из родительской формы с помощью метода Resolve Autofac. У меня возникают проблемы с тем, как форма ребенка остается открытой. В методе дочерней формы Display(), если я вызываю ShowDialog(), дочерняя форма остается открытой, пока я ее не закрою. Если я звоню Show(), дочерняя форма вспыхивает и мгновенно закрывается - что явно не хорошо.Ошибка интеграции с Autofac и WinForms

Я провел многочисленные поиски интеграции Autofac в приложение WinForms, однако я не нашел хороших примеров интеграции Autofac/WinForms.

Мои вопросы:

  1. Что такое правильный способ отображения немодальное формы ребенка с моим подходом?
  2. Есть ли лучший способ использовать Autofac в приложении WinForms, чем мой подход?
  3. Как определить, нет ли утечек памяти и что Autofac правильно очищает объекты Model/View/Presenter для дочерней формы?

Только соответствующий код показан ниже.

Спасибо,

Kyle

public class MainPresenter : IMainPresenter 
{ 
    ILifetimeScope container = null; 
    IView view = null; 

    public MainPresenter(ILifetimeScope container, IMainView view) 
    { 
     this.container = container; 
     this.view = view; 
     view.AddChild += new EventHandler(view_AddChild); 
    } 

    void view_AddChild(object sender, EventArgs e) 
    { 
     //Is this the correct way to display a form with Autofac? 
     using(ILifetimeScope scope = container.BeginLifetimeScope()) 
     { 
      scope.Resolve<ChildPresenter>().DisplayView(); //Display the child form 
     } 
    } 

    #region Implementation of IPresenter 

    public IView View 
    { 
     get { return view; } 
    } 

    public void DisplayView() 
    { 
     view.Display(); 
    } 

    #endregion 

} 

public class ChildPresenter : IPresenter 
{ 
    IView view = null; 

    public ChildPresenter(IView view) 
    { 
     this.view = view; 
    } 

    #region Implementation of IPresenter 

    public IView View 
    { 
     get { return view; } 
    } 

    public void DisplayView() 
    { 
     view.Display(); 
    } 

    #endregion 

} 


public partial class ChildView : Form, IView 
{ 
    public ChildView() 
    { 
     InitializeComponent(); 
    } 

    #region Implementation of IView 

    public void Display() 
    { 
     Show(); //<== BUG: Child form will only flash then instantly close. 
     ShowDialog(); //Child form will display correctly, but since this call is modal, the parent form can't be accessed 
    } 

    #endregion 

} 

ответ

2

Посмотрите на этот код:

using(ILifetimeScope scope = container.BeginLifetimeScope()) 
{ 
    scope.Resolve<ChildPresenter>().DisplayView(); //Display the child form 
} 

Во-первых, это хорошо, что вы использовали всю жизнь ребенка объем. Если вы решите выйти из контейнера верхнего уровня, объекты будут жить до тех пор, пока этот контейнер (обычно это время жизни приложения).

Однако есть проблемы. Когда DisplayView звонит Form.Show, он немедленно возвращается. Блок using заканчивается, область содержимого дочернего объекта и все его объекты (включая представление) также расположены.

В этом случае вам не нужен оператор using. То, что вы хотите сделать, - связать область охвата дочернего процесса с представлением, чтобы при закрытии представления была выделена область с дочерними элементами. См. Пример the FormFactory in one of my other answers. Существуют и другие способы адаптации этой идеи к вашей архитектуре - например, вы можете сделать это при регистрации (ContainerBuilder).

Смежные вопросы