Mvp View knows Model

人盡茶涼 提交于 2020-01-02 07:23:06

问题


I'm trying to use MVP and I notice that my View must know Model that should not happen in MVP I presume.

here is example:

public partial class TestForm : Form, ITestView
{
    public void LoadList(IEnumerable<AppSignature> data)
    {
        testPresenterBindingSource.DataSource = data;
    }
}

public interface ITestView
{
    event EventHandler<EventArgs> Load;
    void LoadList(IEnumerable<AppSignature> data);
}

public class TestPresenter
{
   private ITestView view;

   public TestPresenter(ITestView view)
   {  
       this.view = view;
       view.Load += View_Load;
   } 

   private void View_Load(object sender, EventArgs e)
   {
       var data = // get from model
       view.LoadList(data);
   }
}

and the problem is that in TestForm I need reference to AppSignature. In all tutorials I saw, there are some simple examples like public void LoadList(IEnumerable<String> data) where there is no need reference to model. But how i.e DataGridView can publish current row data?


回答1:


Your form is a View, it is not a Presenter. Thus it should implement interface ITestView:

public interface ITestView
{
    event EventHandler Load;
    void LoadList(IEnumerable<AppSignatureDto> data);
}

And your Presenter is someone, who subscribes to view's events and uses view properties to read and update view:

public class TestPresenter
{
   private ITestView view;

   public TestPresenter(ITestView view)
   {  
       this.view = view;
       view.Load += View_Load;
   } 

   private void View_Load(object sender, EventArgs e)
   {
       List<AppSignature> signatures = // get from model
       List<AppSignatureDto> signatureDtos = // map domain class to dto
       view.LoadList(signatureDtos);
   }
}

And you form, as I already said, is a view, it does not know anything about presenter and model:

public partial class TestForm : Form, ITestView
{
    public event EventHandler Load;    

    private void ButtonLoad_Click(object sender, EventArgs e)
    {
        if (Load != null)
            Load(this, EventArgs.Empty);
    }

    public void LoadList(IEnumerable<AppSignatureDto> data)
    {
        // populate grid view here
    }
} 

How to deal with reference to domain classes? Usually I provide to view only simple data (strings, integers, dates, etc), or I create data transfer objects, which are passed to view (you can name them FooView, FooDto, etc). You can easily map them with something like AtoMapper:

List<AppSignatureDto> signatureDtos = 
      Mapper.Map<List<AppSignature>, List<AppSignatureDto>>(signatures);



回答2:


The View may have knowledge of Model as long as the interaction is limited to data binding only. i.e. View should not try to manipulate Model directly. View will always redirect user input to Presenter and Presenter will take care of further actions. If any action performed by Presenter results in a change in state of Model, Model will notify View via data binding. Model will be completely unaware of existence of View.




回答3:


Is it OK to get DataSource in Presenter and there set its DataSource ? e.g. Presenter code:

Public void LoadData()
{
    _view.Data.DataSource = Business.GetData().ToList();
}

Form code:

Public BindingSource Data
{
    get
    {
        return this.bsData;
    }
}

Thanks to that I dont need to add any references to the View, but I didn't see that solution in any other sources.



来源:https://stackoverflow.com/questions/13015999/mvp-view-knows-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!