Monday 25 May 2009

Model View Presenter (MVP) Pattern

Model-View-Presenter is a user interface design pattern engineered to facilitate automated unit testing and improve the separation of concerns in presentation logic.

The Model is an interface defining the data to be displayed or otherwise acted upon in the user interface.

The View is an interface that displays data (the Model) and routes user commands to the Presenter to act upon that data.

The Presenter acts upon the Model and the View. It retrieves data from repositories, persists it, manipulates it, and determines how it will be displayed in the View.

The degree of logic permitted in the View varies among different implementations.

At one extreme, the View is entirely passive, forwarding all interaction operations to the Presenter. In this formulation, when a user triggers an event method of the View, it does nothing but invoke a method of the Presenter which has no parameters and no return value. The Presenter then retrieves data from the View through methods defined by the View interface. Finally, the Presenter then operates on the Model and updates the View with the results of the operation.

Other versions of Model-View-Presenter allow some latitude with respect to which class handles a particular interaction, event, or command. This is often more suitable for web-based architectures, where the View, which executes on a client's browser, may be the best place to handle a particular interaction or command.

From a layering point of view, the Presenter class might be considered as belonging to the application layer in a multilayered architectured object-oriented system with common layers but it can also be seen as a Presenter layer of its own between the Application layer and the User Interface layer.

 

Sample of MVP implementation in few steps:

1) create an interface (later in the topic will be note like view-interface ) with properties  which will contain values from webpage/form.

public interface IDataView {
string FirstName { get; }
string LastName { get; }
string Status { set; get; } }

2) make webpage/form to implement this interface

public partial class MyPage : System.Web.UI.Page,IDataView


3) implement interface members and map them to webpage/form entries (such labels, textboxes, etc.)

public string FirstName { get { return this.tbFirstName.Text; } }
public string LastName { get { return this.tbLastName.Text; } }
public string Status { set { this.lblStatus.Text = value; }
get { return this.lblStatus.Text; } }


4) create new class for presenter

public class DataPresenter { }


5) declare a variable of view-interface type (created at point 1), variable value will be initialized through constructor

public class DataPresenter
{
private IDataView _view;
}


6) create/extend constructor with input parameter of view-interface type

public class DataPresenter
{
private IDataView _view;
public DataPresenter(IDataView view) { _view = view; }
}


7) create public method(s) for manipulate with view

public class DataPresenter
{
private IDataView _view;
public DataPresenter(IDataView view) { _view = view; }
public void SaveData() {
_view.Status = string.Format("FirstName={0}; LastName={1}",
_view.FirstName, _view.LastName);
}
}


8) in webpage/form create an instance of the presenter, constructor requires input value of view-interface type. Because the webpage/form already implements an view-interface, input value for constructor will be this.

private DataPresenter _presenter;

protected void Page_Load(object sender, EventArgs e)
{
_presenter = new DataPresenter(this);
}


9) now you can calling presenter’s method(s) from the events etc. If the presenter method change view’s data you’ll get back updated data automatically based on mapping from point 3.

protected void Page_Load(object sender, EventArgs e)
{
_presenter = new DataPresenter(this);
btnSave.Click += delegate { _presenter.SaveData(); };
}


In my sample I called the SaveData method on  _presenter presenter.

Wednesday 20 May 2009

Visual Studio 2010 Beta 1

VS2010 is now available for wide audience. Download your copy from following locations:

  • Visual Studio 2010 Team Suite Beta 1

http://download.microsoft.com/download/5/1/8/518B204C-1DF9-4666-B8D4-FAC0375FADB2/VS2010Beta1ENU_VSTS.iso

  • Visual Studio 2010 Team Foundation Server Beta 1

http://download.microsoft.com/download/6/1/7/61788179-96DF-4E60-B65A-A060F28D1F22/VS2010Beta1ENU_TFS.iso

More info at http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx

Some tips to increase performance of your web site.






You're most likely familiar with the paradox - whether you're using brand-new technologies and have top hardware it looks your web is slow. Please find below some tips that can help you to improve web's performance.

1) Set debug="false" under compilation as follows:

<compilation language="c#" debug="false"></compilation>

2) Use Server.Transfer instead of Response.Redirect

3) Always check Page.IsValid when using Validator Controls

4) Use For Each loop instead of For loop for String Iteration.

5) Use Client-Side Validation. (but not all the time you have to validate even on the server side)

6) Check Page.IsPostBack to avoid repetition code execution.

7) Set trace enabled="false" unless until required. (by default it's off, use on the pages where it's required)

<trace enabled="false" requestlimit="10" pageoutput="false" tracemode="SortByTime" localonly="true"></trace>

8) Precompiled pages and disable AutoEventWireup; setting AutoEventWireup="false" in the Machine.config file.

9) If not required, set SessionState mode="Off".

<SessionState timeout="20" cookieless="false" mode="Off" StateConnectionString="tcpip=127.0.0.1:42424" SqlConnectionString="data source=127.0.0.1;Trusted_Connection=no"></SessionState>

10) Select the Release mode before making the final Build for your application. (by default, the mode is Debug)

11) Disable ViewState by setting EnableViewState="false" when not required.

12) Use Using as much as possible. This not very documented feature defines a scope, outside of which an object or objects will be disposed. VB.NET/C#, via the .NET Framework common language runtine, automatically releases the memory used to store objects that are no longer required. The release of memory is non-deterministic; memory is released whenever the CLR decides to perform garbage collection. However, it's usually best to release limited resources such as file handles and network connections as quickly as possible. The Using statement allows the programmer to specify when objects that use resources should release them. The object provided to the Using statement must implement the IDisposable interface. This interface provides the Dispose method, which should release the object's resources. A Using statement can be exited either when the end of the Using statement is reached or if an exception is thrown and control leaves the statement block before the end of the statement.

Dim sContent As String
Using sr As New IO.StreamReader("C:\test.txt")
sContent = sr.ReadToEnd
sr.Close()
End Using

13) Use Caching to improve the performance of your application.

i. Page output caching:
<%@ OutputCache duration="3600" varybyparam="none" %>

ii. Page fragment caching:
Write a Page output caching code into each User Control.

iii. Data caching:
Imports System.Data.SqlClient
Imports System.Data


Partial Class _Default
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load


Dim dv As DataView = Cache.Get("ProductDataView")

If dv Is Nothing Then
Using conn As New SqlConnection("Data Source=LAPTOP;Initial Catalog=Customers;Integrated Security=True")


Using da As New SqlDataAdapter("Select ProductId, ProductName From dbo.Product (noLock)", conn)

Using ds As New DataSet
da.Fill(ds, "Product")
dv = ds.Tables("Product").DefaultView
Cache.Insert("ProductDataView", dv)
End Using
End Using
End Using
Else

Response.Write("<h2>Loaded Data From Cache</h2>")
GridView1.DataSource = dv
GridView1.DataBind()
End If
End Sub

End Class

14) Use Finally method to kill resources. (but not in the case of Using)

15) The String and StringBuilder magic.

It's nice to use StringBuilder instead of String when string are Amended. Strings occupy different memory location in every time of amended where StringBuilder use single memory location.

Dim vars As New StringBuilder
For Each sv As String In Request.ServerVariables
vars.Append(sv & "<br />")
Next
Response.Write(vars.ToString.ToLower)

16) Use strString = String.Empty instead of strString = ""

17) Never use object value directly; first get object value in local variable and then use. It takes more time than variable reading.

18) Don't make the member variables Public or Protected, try to keep Private and use public/protected as properties.

19) Avoid Exceptions: Use If condition (if it is check proper condition).

20) Code Optimalization: Avoid using code like x = x + 1; it's better to use x += 1.

21) Data Access Techniques: DataReaders provide a fast and efficient method of data retrieval. DataReader is much faster than DataSets as far as performance is concerned.

22) Before doing a bulky ASP code processing, you can check to make sure Response.IsClientConnected.

23) Avoid Session variables because each ASP page runs in a different thread and session calls will be serialized one by one. So, this will slow down the application. Instead of Session variables you can use the QueryString collection or hidden variables in the form which holds the values.

24) To improve performance, set Response.Buffer = True.

<% Response.Buffer = True %>

Then use:

<% Response.Flush = True %>

25) Avoid frequent round trips to the Database.

26) Use Repeater control instead of DataGrid, DataList because it's efficient, customizable, and programmable.

27) Data listing is more time consume when large data are retrieve from Database.

Paging will display only particular data but take load of all data.

Fetch only data that is needed for current page.

28) Reduce Cookie size.

29) Avoid Inline JavaScript and CSS.

30) Use single CSS file instead of multiple CSS files.

Lot of .CSS files will cause a large amount of requests, regardless of the file sizes.

.CSS files are normally cached by browsers, so a single and heavy .CSS file doesn't cause a long wait on each page request.

Inline .CSS classes could make HTML heavy.

31) Compress CSS, JavaScript, Images and try use server side compression.

CSS compression tool

JavaScript compression tool

Image compression: GIF and PNG are similar, but PNG typically produces a lower file size (Note: some browser not supporting PNG format)

Server side compression tool

Speed up page loading

Often you find yourself waiting after you made changes in code behind. Delay during first page load has to do with code compilation. With simple modification of web.config you can speed up this process a bit. Main issue is that ASP.NET engine by default compiles all files in folder where you page is place. But you can tell to engine that you are interested only current page and it is related controls/components etc. Do simple change:

Under <configuration><system.web> you can find <compile> element if it does not exists create it. In <compilation> element specify attribute batch with value false.

Changed part of your web.config should looks like:

<compilation batch="false">