How to call Application.Run () for the main host application MVP WinForms?

I am studying the application of MVP to a simple WinForms application (only one form) in C # and ran into a problem while creating the main presenter in static void Main(). Is it a good idea to expose a view from a presenter to provide it as an Application.Run () parameter?

Currently, I have implemented an approach that allows me not to expand the view as a Presenter property:

    static void Main()
    {
        IView view = new View();
        Model model = new Model();
        Presenter presenter = new Presenter(view, model);
        presenter.Start();
        Application.Run();
    }

Presenter start and stop methods:

    public void Start()
    {
        view.Start();
    }

    public void Stop()
    {
        view.Stop();
    }

Start and stop methods in a view (Windows form):

    public void Start()
    {
        this.Show();
    }

    public void Stop()
    {
        // only way to close a message loop called 
        // via Application.Run(); without a Form parameter
        Application.Exit();
    }

Calling Application.Exit () looks like an inelegant way to close the form (and the application). Another alternative would be to expose the view as a public Presenter property to call Application.Run () with the form parameter.

    static void Main()
    {
        IView view = new View();
        Model model = new Model();
        Presenter presenter = new Presenter(view, model);
        Application.Run(presenter.View);
    }

"" "" Presenter . :

    public void Start()
    {
        view.Start();
    }

    public void Stop()
    {
        view.Stop();
    }

    // New property to return view as a Form for Application.Run(Form form);
    public System.Windows.Form View
    {
        get { return view as Form(); }
    }

"" "" ( Windows) :

    public void Start()
    {
        this.Show();
    }

    public void Stop()
    {
        this.Close();
    }

- , ? ?

+4
4

:

// view
public void StartApplication() // implements IView.StartApplication
{ 
    Application.Run((Form)this);
}

// presenter
public void StartApplication()
{
    view.StartApplication();
}

// main
static void Main()     
{     
    IView view = new View();     
    Model model = new Model();     
    Presenter presenter = new Presenter(view, model);     
    presenter.StartApplication();     
}     

, . , , " ", .

+9

. , , void Main, , ( , , winform )

Application.Run(view as Form);
+5

, (, ) . , . Application.Run() Application.Run(ApplicationContext) .

IoC (, / ), . , IoC, , - IoC:

internal static class Program
{
    [STAThread]
    private static void Main()
    {
        ApplicationActions.ExitApplication = Application.Exit;

        MainPresenter mainPresenter = new MainPresenter(new MainView(), new Model());
        mainPresenter.Start();

        Application.Run(); 
    }
}

public static class ApplicationActions
{
    public static Action ExitApplication { get; internal set; }
}

public class MainPresenter : Presenter
{
    //...

    public override void Stop()
    {
        base.Stop();

        ApplicationActions.ExitApplication();
    }
}

IoC. , , , , ApplicationActions.ExitApplication . ExitApplication , . :.

public static Action ExitApplication
{
    get
    {
        return ServiceLocator.GetInstance<Action>("ExitApplication");
    }
}
+1

, . , , , , GUI. , ( ):

1) , , . new View().Start();

// your reusable MVP framework project 
public interface IPresenter<V>
{
    V View { get; set; }
}
public interface IView<P>
{
    P Presenter { get; }
}
public static class PresenterFactory
{
    public static P Presenter<P>(this IView<P> view) where P : new()
    {
        var p = new P();
        (p as dynamic).View = view;
        return p;
    }
}

// your presentation project
public interface IEmployeeView : IView<EmployeePresenter>
{
    void OnSave(); // some view method
}
public class EmployeePresenter : IPresenter<IEmployeeView>
{
    public IEmployeeView View { get; set; } // enforced

    public void Save()
    {
        var employee = new EmployeeModel
        {
            Name = View.Bla // some UI element property on IEmployeeView interface
        };
        employee.Save();
    }
}

// your view project
class EmployeeView : IEmployeeView
{
    public EmployeePresenter Presenter { get; } // enforced

    public EmployeeView()
    {
        Presenter = this.Presenter(); // type inference magic
    }

    public void OnSave()
    {
        Presenter.Save();
    }
}

, , . - :

// your reusable MVP framework project 
public interface IPresenter<P, V> where P : IPresenter<P, V> where V : IView<P, V>
{
    V View { get; set; }
}
public interface IView<P, V> where P : IPresenter<P, V> where V : IView<P, V>
{
    P Presenter { get; }
}
public static class PresenterFactory
{
    public static P Presenter<P, V>(this IView<P, V> view)
        where P : IPresenter<P, V>, new() where V : IView<P, V>
    {
        return new P { View = (V)view };
    }
}

// your presentation project
public interface IEmployeeView : IView<EmployeePresenter, IEmployeeView>
{
    //...
}
public class EmployeePresenter : IPresenter<EmployeePresenter, IEmployeeView>
{
    //...
}

  • .

:

  • IEmployeeView
  • PresenterFactory PresenterFactory this
  • ,
  • , new EmployeeView()...

2) . new Presenter().Start();

(, 1) , .

// your reusable MVP framework project 
public abstract class IPresenter<V> // OK may be a better name here
{
    protected V View { get; }

    protected IPresenter()
    {
        View = ...; // dependenchy injection or some basic reflection, or pass in view to ctor
        (View as dynamic).Presenter = this;
    }
}
public interface IView<P>
{
    P Presenter { get; set; }
}

// your presentation project
public interface IEmployeeView : IView<EmployeePresenter>
{
    void OnSave(); // some view method
}
public class EmployeePresenter : IPresenter<IEmployeeView>
{
    public void Save()
    {
        var employee = new EmployeeModel
        {
            Name = View.Bla // some UI element property on IEmployeedView interface
        };
        employee.Save();
    }
}

// your view project
class EmployeeView : IEmployeeView
{
    public EmployeePresenter Presenter { get; set; } // enforced

    public void OnSave()
    {
        Presenter.Save();
    }
}

:

  • IEmployeeView
  • ,
  • , new EmployeePresenter(...

3) ,

( ), , 1, ( ), 2, , , . :

// your reusable MVP framework project
public abstract class IPresenter<V> where V : IView
{
    protected V View { get; }

    protected IPresenter()
    {
        View = ...; // dependenchy injection or some basic reflection, or pass in view to ctor
        WireEvents();
    }

    protected abstract void WireEvents();
}

// your presentation project
public interface IEmployeeView : IView
{
    // events helps in observing
    event Action OnSave; // for e.g.
}
public class EmployeePresenter : IPresenter<IEmployeeView>
{
    protected override void WireEvents()
    {
        View.OnSave += OnSave;
    }

    void OnSave()
    {
        var employee = new EmployeeModel
        {
            Name = View.Bla // some UI element property on IEmployeedView interface
        };
        employee.Save();
    }
}

// your view project
class EmployeeView : IEmployeeView
{
    public event Action OnSave;
    void OnClicked(object sender, EventArgs e) // some event handler
    {
        OnSave();
    }
}
// you kick off like new EmployeePresenter()....

:

  • , -

:

  • IEmployeeView
  • , iview
  • , iview
  • , new EmployeePresenter()...

. , #, , , . , ! , , .NET (, Form of WinForms) . , . , # IEmployeeView , , IEmployeeView , (. IEmployeeView EmployeeView ). , #, , .

4)

.

// your presentation project
public interface IEmployeeView
{
    void OnSave(); // some view method
}
public static class EmployeePresenter // OK may need a better name
{
    public void Save(this IEmployeeView view)
    {
        var employee = new EmployeeModel
        {
            Name = view.Bla // some UI element property on IEmployeedView interface
        };
        employee.Save();
    }
}

// your view project
class EmployeeView : IEmployeeView
{       
    public void OnSave()
    {
        this.Save(); // that it. power of extensions.
    }
}

:

  • -

:

  • IEmployeeView
  • , this.... this....
  • , View...

2 3 .

0

Source: https://habr.com/ru/post/1743797/


All Articles