Have you encountered long-running ASP.NET projects?
Maybe you are working on such a project right now?
If so, then you are most likely faced with a complexly intertwined set of events, logic, and validations within the classes of pages.
This article talks about how to simplify life on such projects using the same Model-View-Presenter template.
I will assume that you are familiar with the MVC template and will not dwell on it in this article.
I will try to compare MVC with the features that classic ASP.NET provides:
1. Routing - processing requests
In most cases, the folder tree of a site can serve the same purpose.
')
2. View and PartialView - data view
The Page class and the UserControl accordingly are great for this purpose.
3. Model - data
Model classes are most likely present in your system in any form.
4. Presenter - glue between data and presentation
Unfortunately, this type of ASP.NET object does not provide.
We will deal with the implementation of the presenter now.
The purpose of the presenter is to prepare data for display to the user and process the data entered by him.
The purpose of the view is to show data to the user and receive data from the user.
There are different opinions about how clever a presentation and a presenter can be.
Since there is no consensus, I prefer to proceed from the effectiveness of the implementation, which depends on the environment. In this case, from the existing library ASP.NET which has a wide range of fairly smart controls that I would like to use to the fullest extent, since such an opportunity is present.
Finally proceed to the implementation.
We create two classes PageView and UserControlView:
public abstract class PageView<T>: Page where T : class { private T _presenter; public T Presenter { get { return _presenter ?? (_presenter = CreatePresenter()); } } protected abstract T CreatePresenter(); } public class UserControlView<T> : UserControl { public T Presenter { get; set; } }
The PageView class is abstract and involves the creation of a presenter in the child itself.
The UserControlView class has a single property, Presenter, which is initialized by the parent on which the user element is located.
It is assumed that the page presenter contains the presenters of its user elements.
An example of the implementation of the list and its element:
List.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="List.aspx.cs" Inherits="WebApplication1.Client.List" EnableViewState="false" %> <%@ Register TagPrefix="ctl" TagName="Item" Src="Details.ascx" %> <asp:Content ContentPlaceHolderID="MainContent" runat="server"> <asp:Repeater ID="ctlList" runat="server" > <ItemTemplate> <ctl:Item runat="server" Presenter="<%# Container.DataItem %>" /> </ItemTemplate> </asp:Repeater> </asp:Content>
List.aspx.cs
public partial class List : PageView<ListPresenter> { protected override ListPresenter CreatePresenter() { return new ListPresenter(); } protected override void OnLoad(System.EventArgs e) { base.OnLoad(e); ctlList.DataSource = Presenter.Items; ctlList.DataBind(); } }
Details.aspx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Details.ascx.cs" Inherits="WebApplication1.Client.Details" %> <asp:TextBox runat="server" Text="<%# Presenter.Model.FirstName %>" OnTextChanged="OnFirstNameChanged" /> <asp:TextBox runat="server" Text="<%# Presenter.Model.LastName %>" OnTextChanged="OnLastNameChanged" /> <asp:Button runat="server" Text="Save" OnClick="OnSave" /> <br />
Detalis.aspx.cs
public partial class Details : UserControlView<DetailsPresenter> { protected void OnFirstNameChanged(object sender, System.EventArgs e) { Presenter.Model.FirstName = ((TextBox) sender).Text; } protected void OnLastNameChanged(object sender, System.EventArgs e) { Presenter.Model.LastName = ((TextBox)sender).Text; } protected void OnSave(object sender, System.EventArgs e) { Presenter.Save(); } }
By the way, please note, ViewState on the pages is turned off.
The full example can be downloaded
here .
The advantages of this approach:
1. Page code becomes much easier.
2. You can write unit tests for classes presenters
3. You can use presenters to implement various interfaces (web, win, mobile)
4. Can be used in conjunction with the noodle and upgrade the application gradually.
I hope my experience will be useful to you.