Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Presentation Model and Dependency Injection

0.00/5 (No votes)
26 Apr 2009 1  
ASP.NET MVVM provides a framework to implement the Presentation Model pattern, a.k.a. the Model-View-ViewModel pattern in ASP.NET projects. Developers can take advantages of Dependency Injection and Event Broker to write concise, elegant and business focused code.
pm_on_azure.png

Introduction

Presentation Model is the design pattern to separate content from presentation and data processing (model) from content. In my other article titled Presentation Model in Action, I demonstrated how to use the Presentation Model pattern in web sites, Windows Forms applications and WPF applications.

Model-View-ViewModel (MVVM, M-V-VM) pattern is another name of the Presentation Model pattern. In the recently published MSDN magazines, there are two articles about using the MVVM pattern in WPF (February, 2009) and Silverlight (March 2009). Maybe in the next issue of MSDN magazine, they will publish another article about using MVVM in ASP.NET.

Meanwhile, I have introduced the Dependency Injection and Event Broker into the pattern and have created a new project, named ASP.NET MVVM Framework on CodePlex. I will keep using the term Presentation Model pattern below in this article to describe how Dependency Injection and Event Broker can play a role for the pattern on ASP.NET platform.

Dependency Injection

Within the Presentation Model pattern, there is a centralized place to store state/data. It is also a centralized event source which is completely independent from the views.

ASPNET_MVVM_Solution_-_1

The diagram above from MSDN shows that the relationships between the objects are:

  • View references to Presentation Model
  • View subscribes to Presentation Model’s events
  • Presentation Model references to Model
  • Presentation Model subscribes to Model’s events

When the pattern is used on ASP.NET platform:

  • View references to Presentation Model through interfaces for decoupling and testability
  • Presentation Model implements interfaces required by many Views
  • Presentation Model instance is shared by many Views. E.g. a Presentation Model instance created on web form (ASPX) is shared by all user controls (ASCX) on the web form

The View knows only an interface, not the type of the Presentation Mode. The View does not know how to create the Presentation Model instance. Also the Presentation Model instance is shared between many Views. None of the Views own the Presentation Model instance.

To manage the objects here, the Inversion of Control principle comes into the picture. It brings two other patterns, the Service Locator pattern and the Dependency Injection pattern.

If using the Service Locator pattern, there is a Service Locator class that knows how to create Presentation Model instances. This class also contains references to Presentation Model instances. The View calls the Service Locator class to get references of the Presentation Model instances.

public ICustomerList controller {get; set;}
protected void Page_Load(object sender, EventArgs e)
{
    controller = ControllerLocator.GetController(this) as ICustomerList;
    customerGrid.DataSource = controller.Customers;
}

If using the Dependency Injection pattern, it works just like the Hollywood principle, “Don't call us, we will call you”. The View does not even know where the helper is. The View only marks where the Presentation Model instances are needed. Right after the View is created, the Presentation Model instances are there ready for use. This is done through a custom HttpModule in the ASP.NET MVVM Framework.

[Inject]
public ICustomerList controller {get; set;}
protected void Page_Load(object sender, EventArgs e)
{
    customerGrid.DataSource = controller.Customers;
}

There are many frameworks that provide the dependency injection function, for example Unity. The main difference between the ASP.NET MVVM Framework and other frameworks is that the ASP.NET MVVM Framework does not create special containers. Presentation Model instances are stored in the control tree by default. When searching for the Presentation Model instances, the ASP.NET MVVM Framework looks into the control tree to find them. It searches user control’s parent, then the parent of the parent until no parent is found. Nested user control hierarchy is supported. This flexibility enables us to keep using the user controls as the application building blocks.

The Presentation Model instances can be stored in ASP.NETs intrinsic object storage, Application, Session and the Request.

[Inject(Scope=InjectScope.Application)]
public ILogger logger {get; set;}

[Create(Scope=CreationScope.Session)]
public CustomerController controller {get; set;}

protected void Page_Load(object sender, EventArgs e)
{
}

Event Broker

In the Presentation Model pattern, the Presentation Model publishes events and the View subscribes to the events. The Event Broker pattern offers an elegant method to manage this publication and subscription relationship.

In the Microsoft Composite UI Application Block, there is an event broker system that enables to publish and to subscribe events between components. An event publisher publishes events like below:

[EventPublication("event://UpdatesAvailable", PublicationScope.Global)]
public event SomeEventHandler UpdatesAvailable;

An event consumer subscribes to events like below:

[EventSubscription("event://UpdatesAvailable")]
public void NewUpdates(object sender, SomeEventArgs numUpdates)
{
}

The ASP.NET MVVM brings this pattern to ASP.NET and simplifies it:

  1. All events in the Presentation Model are published.
    The ASP.NET MVVM assumes all public events in the Presentation Model are published. There is no need for the Event Publication Attribute. By doing so, the Presentation Model has no dependency on the ASP.NET MVVM Framework. We should be able to reuse the Presentation Model in other application platforms, such as WPF and Silverlight without any change. 
  2. Event names are event topics.
    The ASP.NET MVVM Framework matches the publication and subscription by the event name and function name by default. It can also match them by providing the event name and property name of the Presentation Model instance. E.g. the event and functions below will match:
// The event in the Presentation Model / ViewModel
public event EventHandler CustomerChanged;

// In the View, subscribe to event with same name 
[EventSubscription]
private void CustomerChanged(object sender, EventArgs e)
{
}

// In the View, subscribe to event that matches a name 
[EventSubscription(EventName= “CustomerChanged”)]
private void controller_CustomerChanged(object sender, EventArgs e)
{
}

// In the View, subscribe to event that matches a name 
// and the Presentation Model property name 
[EventSubscription(EventName=“CustomerChanged”, ControllerName=”controller”)]
private void controller_CustomerChanged(object sender, EventArgs e)
{
}

In ASP.NET, if subscribed to some events when page loaded, the events must be unsubscribed when page unloaded. Otherwise if the event publisher is in Session or Application, it holds references to the event handler in the View. The View then will not be garbage collected, which could cause memory leak.

[Inject]
public ICustomerList controller { get; set;}
protected void Page_Load(object sender, EventArgs e)
{
    controller.CustomerListChanged += new EventHandler(CustomerListChanged);
}

protected void Page_Unload(object sender, EventArgs e)
{
    controller.CustomerListChanged -= new EventHandler(CustomerListChanged);
}

To prevent memory leak, the ASP.NET MVVM Framework stores the events and subscribing method links. When web page unloads, the ASP.NET MVVM Framework un-subscribes the events using the stored links. This is done behind the scenes. No unsubscribing code is required in the View.

Use the Code

The Dependency Injection and Event Broker discussed above are implemented in a lightweight framework that you can download from the link at the top of this article. It is designed specifically for the ASP.NET platform. To use it, add a reference to the project and add the HttpModule in web.config under the <httpModules> section.

<add name="PageControllerModule" 
	type="Demo.Web.Mvvm.PageControllerModule, Demo.Web.Mvvm"/>

That’s all you need. Now you can start to enjoy the [Create], [Inject] and [EventSubscription] attributes.

The sample application comes from my previous article, but is re-written using the attributes. The application runs not only on regular Windows servers, but also works on the Windows Azure platform. I have tested it on Windows Azure. The screenshot at the top of this page shows the sample application running on Windows Azure.

Conclusion

ASP.NET MVVM is designed to implement the Model-View-ViewModel pattern, a.k.a. the Presentation Model pattern in ASP.NET projects. Developers can take advantage of Dependency Injection and Event Broker to write concise, elegant and business focused code. It offers the following benefits:

  • Leverages ASP.NET functions, such as web form, user control and data binding
  • Achieves a clear separation of concerns
  • Facilitates test driven development (TDD)
  • Writes and maintains simpler code using the attribute annotations

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here