Monthly Archives: July 2009

MVC vs. MVP vs. MVVM

An important FAQ. The answer actually depends on where the person is coming from. MVC is a fundamental pattern which has been tweaked quite a bit to fit into various platforms. For instance if you had asked anybody how to implement an MVC in ASP.NET (prior to release of ASP.NET MVC framework) you would get very different answers. So let’s start with basic. The common motivation behind all 3 is separation of concerns, cutting flab from UI (good for UI designers), swapping UIs (for instance windows to web), make UI easy for Unit Testing, etc. Have a look at the below diagram, I have taken it from CAB documentation.

MVCMVP

MVC: Three components – View (your UI), Model (your business entities / data – that view is displaying) & Controller (contains the logic that alters the model depending on the action triggered by UI, typically implementing a Use Case). It’s widely known that MVC is a compound pattern (View and Controller have Strategy implementation, View itself can be a Composite implementation & View and Model are synched through Observer). In this case Controller doesn’t know anything about View, and the idea is that a View can switch Controllers (for instance depending upon who has logged to the system) & a single controller can be used by multiple Views. View subscribes to the changes done to the model & hence both are sync from the data perspective. One of the disadvantages of MVC is that it’s difficult to unit test. Controller manipulates the data but how about asserting those changes from a view perspective. For instance on click of a button you raise an event to controller, and controller modifies the value in model. This value modification changes the font size / color in View. Unit testing this scenario is slightly difficult in MVC.

MVP: Again three components. But dependencies change (look at arrows in the diagram). Over here we replace Controller with Presenter (one which presents the changes done in model back to view). The main difference between both is that Presenter refers back to the view while Controller doesn’t. Normal pattern found here is to create an abstraction of the View (in terms of properties / events) & Presenter refers to it. This makes the mocking of View much easier & hence the Unit Testing aspect. Presenter here hence takes the responsibility of not only manipulating model but also updating the view. Of course the implementations of MVP differ in real world in terms of how much thin the view is, some prefer keeping basic logic still inside view & taking complex logic in presenter, while others prefer keeping the entire logic in Presenter. Martin fowler describes 2 variations on MVP on these lines namely – Supervising Controller & Passive View described below

(A Passive View handles this by reducing the behavior of the UI components to the absolute minimum by using a controller that not just handles responses to user events, but also does all the updating of the view. This allows testing to be focused on the controller with little risk of problems in the view.

Supervising Controller uses a controller both to handle input response but also to manipulate the view to handle more complex view logic. It leaves simple view behavior to the declarative system, intervening only when effects are needed that are beyond what can be achieved declaratively.)

MVVM: Model–View-ViewModel talks of creating a new model (in addition to your domain model). This model normally adds additonal properties from the prespective of View (as we understand that View has controls in addition to data which it’s displaying). For instance if View had a property IsChecked and Presenter was setting in classic MVP, in MVVM Presenter will have that IsChecked Property which View will sync up with (doesn’t it look like Strategy pattern has been replaced with Observer?). So now a Presenter becomes more like a combo of – View Properties & Model properties which would be synchronized with View. So why not rename Presenter to ViewModel? Do that and you get MVVM. MVVM is attractive for platforms which support bi-directional binding with less effort. Also a minor tradeoff is ViewModel unlike Presenter can stand on its own (Presenter normally requires a View’s interface). Martin fowler describes similar pattern called Presentation Model & Josh Smith captures MVVM implementation for WPF / Silverlight in this article.

MVVM

ASP.NET MVC: So what has MVC got to do with ASP.NET MVC? First, Web works on a different model. Here, user interacts with HTML in browser and send a request back to the server for processing (for client side Ajax you might go just for data). As the interaction is normally stateless, when the request comes back to the server we need to recreate our View, load the model back & manipulate both of them as required. There are 2 variations on how handle this recreation – Page Controller & Front Controller. Make Page the decision maker – in this widely implemented pattern HTTP request is specific to physical page on server (.aspx for instance) & page in turn creates itself (builds the view from postback data) decides what model it needs and triggers the manipulation (events in codebehind file) it requires. As you see here the distinction between View & Controller becomes blur & is little difficult to separate. This where ASP.NET MVC comes in which behaves like a Front Controller – where Controller is the decision maker. Here all HTTP requests are mapped to methods on the Controller Class. Controller class recreates the model & view as required and does the manipulations. This makes unit testing easier as we can directly instantiate the front controller class & invoke methods on it to perform the assertions.

I can add code snippets to above explanations if you feel they would help you understand things better. I will look forward to your comments :) .

Loading 2 Versions of the same .NET Assembly

This can be an interview question :) . Let’s say I have a class

public class Class1 //1.0.0.0 – in C:
{
public string SayHello()
{
return “Hello World”;
}
}

and I version it to 2.0.0.0

public class Class1 // in C:\2 folder
{
public string SayHello()
{
return “Hello India”;
}
}

So you have 2 assemblies. Now, write a program in .NET to print Hello World & Hello India. Simple – use Assembly.LoadFrom (LoadFrom takes a path while Load goes through Assembly Resolver & Loader).

class Program
{
static void Main(string[] args)
{
Assembly assm = Assembly.LoadFrom(@”C:\ClassLibrary1.dll”);
Type[] types = assm.GetTypes();
foreach (var t in types)
{
Object obj = assm.CreateInstance(t.FullName);
Console.WriteLine(t.GetMethod(“SayHello”).Invoke(obj, null));
}

Assembly assm2 = Assembly.LoadFrom(@”C:\2\ClassLibrary1.dll”);
Type[] types2 = assm2.GetTypes();
foreach (var t in types2)
{
Object obj = assm2.CreateInstance(t.FullName);

Console.WriteLine(t.GetMethod(“SayHello”).Invoke(obj, null));
}
}
}

But to your suprise the output remains – “Hello World” & “Hello World”. If you take the second block first, output will change to “Hello India” & “Hello India”. Neither of them is what we expected. Conclusion – It’s not possible to load 2 assemblies by same name inside a single AppDomain. So you will have to create a seperate AppDomain & load the second version of assembly into it as shown below:

class Program
{
static void Main(string[] args)
{
Assembly assm = Assembly.LoadFrom(@”C:\ClassLibrary1.dll”);
Type[] types = assm.GetTypes();
foreach (var t in types)
{
Object obj = assm.CreateInstance(t.FullName);
Console.WriteLine(t.GetMethod(“SayHello”).Invoke(obj, null));
}
AppDomain app = AppDomain.CreateDomain(“Child”, AppDomain.CurrentDomain.Evidence, new AppDomainSetup { ApplicationBase = @”C:\2″ });
Assembly assm2 = app.Load(@”ClassLibrary1″);
Type[] types2 = assm2.GetTypes();
foreach (var t in types2)
{
Object obj = assm2.CreateInstance(t.FullName);

Console.WriteLine(t.GetMethod(“SayHello”).Invoke(obj, null));
}
}
}

Do you have any better ways?

Tower Servers vs. Rack Servers vs. Blade Servers

Continuing my hardware series let me try to put the basic differences between above three.

Tower Servers are the normal boxes (in appearance) you would have seen in Visio Diagrams. Of course they are very powerful & have bundled software tools to manage them. The problem with Tower Severs is the space they occupy, management personnel they require, and cost of operating them (power, network, etc.).

Rack Servers are servers mounted inside a Rack (something like we normally use to manage our letters, office files, etc.) Major Racks available out there adhere to an IEEE standard and are measured in rack units or “U’s” (each U is 19” wide and 1.75” tall). So a rack server size is typically in multiplication of these “U’s”. Motivation here is to scale vertically than horizontally with more compact physical servers. In addition to this, there are many other electronic devices which adhere to this IEEE standard for instance – Rack Consoles, SAN devices, Power Backup devices, etc. Advantage being that you can fix them into rack as well along with your servers. Not to mention that the hardware vendors (Dell, HP, IBM, etc.) provide additional software tools that help you effectively manage these servers and in some cases the supported devices also.

Blade Servers are an additional level of innovation on top of Rack Servers. Blade Servers are typically placed inside a blade enclosure, and together they form a blade system. A Blade system normally meets the IEEE standard of Rack Units, which means that the entire Blade system can be placed inside the rack along with other electronic equipments. The benefits of blade enclosure includes hot plugging (normally blade servers have a handle attached to them, for transferring them in and out of the blade enclosure – it’s an easy way of identifying them) and stripped modular design (e.g. shared network ports, power connections, switches, etc.). For instance the hardware we ordered allows us to pack 16 blade servers inside a 10U space. I remember meeting an Oracle Consultant few months back where he was touting about a server with no disk. Such scenarios are possible (and are cheaper) by coupling a blade system and SAN storage. All these boils down to further space reduction, cost savings (power, administration staff) & easy management. Bundle this with Virtualization and you have a very powerful infrastructure at your disposal.

So any guesses as to what the next generation of servers would be :) ?

Passing Optional & Unordered Parameters via ODP.NET – PLS-00306

Times change. Recently I was interacting with a team that was using ODP.NET. And they had this stored procedure written in SQL server which they were moving to Oracle DB. They had some challenges in porting their data access code to support Oracle. One of them was – ODP.NET requires all parameters (even if they have default values) to be passed to the Stored Procedure and also expects them in the same order. But with SqlClient the same is not required. Solution to this is use BindByName property of OracleCommand class. Let me elaborate through a small sample code for better understanding:

Dummy

Consider the following dummy procedure using the above Dummy Table
CREATE PROCEDURE [dbo].[DummyProc]
@Age As Int,
@Name As varchar(50) = ‘AA’ –default value
AS
BEGIN
SET NOCOUNT ON;
DECLARE @noOfRows as INT

SELECT * from Dummy d where d.Age = @Age AND d.Name = @Name

SELECT @noofrows = @@rowcount –tSql is not case sensitive
RETURN @noofrows
END
Now the C# code to pass parameters to this would be:

SqlConnection conn = new SqlConnection(@”ConnString”);
conn.Open();
SqlCommand command = conn.CreateCommand();
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = “DummyProc”;
command.Parameters.Add(new SqlParameter(“@Age”, 2)); //Order doesn’t matter
//command.Parameters.Add(new SqlParameter(“@Name”, “AA”)); – This is not required
SqlParameter paramReturnCode = command.CreateParameter();
paramReturnCode.ParameterName = “ReturnCode”;
paramReturnCode.DbType = DbType.Int32;
paramReturnCode.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(paramReturnCode);
command.ExecuteNonQuery();
Console.WriteLine(command.Parameters[@"ReturnCode"].Value);
conn.Close();

//Output
1

Pretty simple. Let’s move the above to oracle now & access it from ODP.NET. First let’s create a stored procedure in Oracle.

create or replace
PROCEDURE DUMMYPROC
( p_Age IN NUMBER
, p_Name IN VARCHAR2 DEFAULT ‘AA’
, p_NoOfRows OUT NUMBER
) AS
BEGIN
select count(*) into p_noofrows from dummy d where d.age = p_Age AND d.name = p_name;
–N.B. In above ‘into’ is required, for select returning a recordset you need a RefCursor
END DUMMYPROC;

Now let’s write some code using ODP.NET (Oracle.DataAccess.dll)

OracleConnection conn = new OracleConnection(@”ConnString”);
conn.Open();
OracleCommand command = conn.CreateCommand();
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = “DummyProc”;
//command.BindByName = true;
command.Parameters.Add(new OracleParameter(“p_Age”, 2));
//command.Parameters.Add(new OracleParameter(“p_Name”, “AA”)); // This is not required
OracleParameter paramReturnCode = command.CreateParameter();
paramReturnCode.ParameterName = “p_NoOfRows”;
paramReturnCode.OracleDbType = OracleDbType.Int32;
paramReturnCode.Direction = ParameterDirection.Output;
command.Parameters.Add(paramReturnCode);
command.ExecuteNonQuery();
Console.WriteLine(command.Parameters[@"p_NoOfRows"].Value);
conn.Close();

The above code on execution throws an error – PLS-00306: wrong number or types of arguments in call to ‘DUMMYPROC’. The issue here is oracle expects all parameters to be passed in same order for faster execution. But as it turns out that it’s not always the case. Run the same Oracle code above but uncomment line no. 7 – command.BindByName = true

And here you are with the expected output.
//Output
1

Hope this helps :) .

I am back :)

mvp

What a way to celebrate a year of blogging!!! Yesterday not only marked a year of this blog (started in June 2008) but I also got my MVP status renewed into a more fitting category of – “Connected Systems Developer”. I wanted to write a detailed blog post about this, explaning the ins & outs of the MVP program but then thought otherwise. As usual, I owe the award to my family (for allowing me to stay away whenever it was required), friends @ Microsoft for providing opportunities to contribute & knowledge to share, and my MVP lead Abhishek. And last but not the least, you guys who make communities such a passionate place. A humble thank you to everyone :) .

Follow

Get every new post delivered to your Inbox.

Join 80 other followers