我是整个MVP的新手,慢慢地让我全神贯注。我遇到的一个问题是如何在填充GridViews时使用MVP方法(和ddls,但我们稍后会解决这个问题)。
将它直接连接到ObjectDataSourceID是否可以?对我而言,这似乎是错误的,因为它绕过了MVP所做的所有关注点分离。
所以,说到这个,我该怎么做?我如何处理排序(我是否将处理程序事件发送到表示层,如果是这样,它在代码中的表现如何)? 现在我有一个没有排序的GridView。代码如下。
ListCustomers.aspx.cs:
public partial class ListCustomers : System.Web.UI.Page, IlistCustomer
{
protected void Page_Load(object sender, EventArgs e)
{
//On every page load, create a new presenter object with
//constructor recieving the
// page's IlistCustomer view
ListUserPresenter ListUser_P = new ListUserPresenter(this);
//Call the presenter's PopulateList to bind data to gridview
ListUser_P.PopulateList();
}
GridView IlistCustomer.UserGridView
{
get { return gvUsers; }
set { gvUsers = value; }
}
}
接口(IlistCustomer.cs):在整个Gridview控件中发送这个错误吗?
public interface IlistCustomer
{
GridView UserGridView { set; get; }
}
Presenter(ListUserPresenter.cs):
public class ListUserPresenter
{
private IlistCustomer view_listCustomer;
private GridView gvListCustomers;
private DataTable objDT;
public ListUserPresenter( IlistCustomer view)
{
//Handle an error if an Ilistcustomer was not sent in)
if (view == null)
throw new ArgumentNullException("ListCustomer View cannot be blank");
//Set local IlistCustomer interface view
this.view_listCustomer = view;
}
public void PopulateList()
{
//Fill local Gridview with local IlistCustomer
gvListCustomers = view_listCustomer.UserGridView;
// Instantiate a new CustomerBusiness object to contact database
CustomerBusiness CustomerBiz = new CustomerBusiness();
//Call CustomerBusiness's GetListCustomers to fill DataTable object
objDT = CustomerBiz.GetListCustomers();
//Bind DataTable to gridview;
gvListCustomers.DataSource = objDT;
gvListCustomers.DataBind();
}
}
答案 0 :(得分:3)
我将首先强调MVP作为模式解决的主要问题。首先,它是通过分离关注点来实现模块化。这意味着理想情况下,可以将View层从Web窗体更改为Windows窗体,而无需在Presenter和Model层中对其进行任何操作。其次,使用MVP设计的应用程序很容易进行单元测试,因为测试表单非常困难。考虑到这一点,您会意识到不应在Presenter层中操作像Grid这样的以视图为中心的对象,因为当View更改时,控件也可能会更改。要回答您的问题,我可以通过以下方式解决您的问题:
// View
public interface IListCustomersView
{
public void BindGrid(IList<Customer> customers);
}
// Form e.g. Web Form, Windows Form
public class ListCustomers : IListCustomersView
{
private ListCustomersPresenter listCustomerPresenter = null;
public ListCustomers()
{
// You can use a Dependency Injector here
this.listCustomersPresenter = new ListCustomerPresenter(
new CustomerRepository(),
this);
}
public void BindGrid(IList<Customer> customers)
{
grid.DataSource = customers;
grid.Databind();
}
}
// Presenter
public class ListCustomersPresenter
{
private readonly IListCustomersView view = null;
private readonly ICustomerRespository repository = null;
public ListCustomersPresenter(
ICustomerRespository customerRepository, IListCustomersView view)
{
Guard.AgainstNull(view,"View");
Guard.AgainstNull(customerRepository,"CustomerRepository");
this.view = view;
this.customerRepository = customerRepository;
}
public void BindGrid()
{
// Fetch customers from repository
IList<Customer> customers = this.customerRepository.GetCustomers();
view.BindGrid(customers);
}
}
答案 1 :(得分:1)
使用数据库感知控件(如Gridview)的便利性是一个巨大的诱惑。从理论上讲,人们可以推出自己的网格视图并坚持MVP设计。但是,你将重复工作,并提供有限的业务资源,而这往往是最明智的选择。由于节省时间可能相当大,因此有充分的理由使用数据库感知控件。
妥协是通过代码清楚地记录控件连接到数据库的路径。这样,当您迁移UI,后端或两者时,您可以看到依赖于数据库感知控件和后端的内容。还要查看框架提供的数据库apis。您可以接近通用选项,以最大限度地减少更改后端的问题。
在规划设计时,要问的关键问题是“如果我更改UI,演示者,视图,模型或数据库后端会发生什么。答案希望能够引导您进行允许更改的设计。” / p>
答案 2 :(得分:1)
视图界面不应公开UI组件;我的意思是以下
public interface IlistCustomer
{
PopulateCustomers(IEnumerable<Customer> customers);
}
public class ListUserPresenter
{
private IlistCustomer _view;
public ListUserPresenter(IlistCustomer view)
{
//Handle an error if an Ilistcustomer was not sent in)
if (view == null)
throw new ArgumentNullException("view");
_view = view;
}
public void PopulateList()
{
//Injecting your DAL seems like a good choice here
CustomerBusiness CustomerBiz = new CustomerBusiness();
IEnumerable<Customer> customers = CustomerBiz.GetListCustomers();
_view.PopulateCustomers(customers);
}
}