After playing around with the Sharepoint 2010 Guidance Package, I decided to implement a MVP pattern within a WebPart using the ServiceLocator component. Let’s start by creating a new Visual WebPart with the according project template in Visual Studio 2010.
This template is a real improvement and generates all components necessary for a Visual WebPart, especially an ASP.NET user control (ASCX), which can be designed using the visual editor in Visual Studio. The following image shows the project structure after executing the template:
The project contains nearly all elements we need for MVP. The WebPart class (VisualWebPart1) will become our model. Actually it’s more kind of a controller and initializes the view and also provides access to data. Of course, the UserControl will be the view. So all we need additionally is the Presenter and some interfaces. Let’s create the interfaces first. We create one for the WebPart class. In the example the interface provides just one method called GetNames, which returns a List of strings just for testing:
public interface IVisualWebPart1
{
System.Collections.Generic.IList<string> GetNames();
}
We also need an interface for the View, so that the Presenter can call the appropriate methods on it without knowing the concrete implementation. In the example the View has a Fill method, which accepts a list of strings:
public interface IVisualWebPart1UserControl
{
void Fill(System.Collections.Generic.IList<string> names);
}
With that interfaces we can now define our Presenter. I will create a generic base class for the Presenter, which can be reused in other projects:
public class Presenter<IView, IModel>
{
public Presenter()
{
IServiceLocator serviceLocator = SharePointServiceLocator.GetCurrent();
Model = serviceLocator.GetInstance<IModel>();
}
public Presenter(SPSite site)
{
if (site != null)
{
IServiceLocator serviceLocator =
SharePointServiceLocator.GetCurrent(site);
Model = serviceLocator.GetInstance<IModel>();
}
}
protected IModel Model { get; set; }
public IView View { get; set; }
public virtual void OnViewInitialized() { }
public virtual void OnViewLoaded() { }
}
The Presenter is the connection between the Model and the View. It expects to get the Model by using the Sharepoint Service Locator. The View property will be set by the View itself upon its creation. The derived Presenter in the example (VisualWebPart1Presenter) uses IVisualWebPart1 as Model and IVisualWebPart1UserControl as View. It overrides OnViewInitialized and calls the Fill method of the View with the list provided by the Model. So all we need to do know is to create the Presenter in the View and call its OnViewInitialized method. The View gets a property of type VisualWebPart1Presenter:
VisualWebPartMVPPresenter _presenter;
VisualWebPartMVPPresenter Presenter
{
get
{
if (_presenter == null)
{
_presenter = new VisualWebPartMVPPresenter(SPContext.Current.Site);
_presenter.View = this;
}
return _presenter;
}
}
We’re nearly done. The last thing to do is to register the Model with Sharepoint Service Locator. As said in my previous post, I will use a feature receiver to do that. A right click on Feature1.Feature opens the context menu and there you find an option to add an event receiver. Visual Studio creates a class derived from SPFeatureReceiver and also adds the important method overrides which you only need to uncomment. Within the FeatureInstalled method add the following code:
using (SPSite site = new SPSite("Add your site URL"))
{
IServiceLocator serviceLocator = SharePointServiceLocator.GetCurrent();
IServiceLocatorConfig typeMappings =
serviceLocator.GetInstance<IServiceLocatorConfig>();
typeMappings.RegisterTypeMapping<VisualWebPart.IVisualWebPart1,
VisualWebPart.VisualWebPart1>();
}
Now we can give it a try. Deploy the WebPart and add it to the WebPart gallery within Sharepoint. When you place it on a site you should be able to see the names list from the model class inside a list box.
The sample project can be downloaded here.
The sample project can be downloaded here.