Chapter 13. Design patterns and testability – SharePoint 2010 Web Parts in Action

Chapter 13. Design patterns and testability

 

 

Design patterns and testability have unfortunately been a low priority for many SharePoint developers. Their focus, instead, has been on understanding the platform and the tools, which until now has been quite a challenge. It’s not that SharePoint developers aren’t interested in building nicely designed and well-tested solutions; it’s that they lack knowledge of design patterns or are too cautious to get involved with using a pattern.

This chapter introduces design patterns in general and shows you how to design your Web Parts to improve

  • Testability
  • Separation of concerns
  • Reusability

There’s one pattern that fits perfectly into the way Web Parts work and interact with the surrounding environment; it’s called the Model-View-Presenter (MVP) design pattern. This pattern allows developers and architects to separate the data model and domain from the business logic and presentation layers and provides a better way to reuse the application logic. You can also apply other design patterns to SharePoint projects. For instance, the Model-View-ViewModel (MVVM) pattern is often used when building rich Silverlight applications.

By using a service provider and service repository called the service locator, you can enhance the flexibility of your applications by providing multiple implementations of the different layers in the application. Using registered services in the application also facilitates the reuse of code and components, and the amount of code you have to maintain decreases.

If you build your Web Parts using a pattern such as MVP, you can take advantage of unit-testing to test the code. Visual Studio 2010 contains efficient tools for testing code using unit-tests; you’ll learn more about that in section 13.4.1.

Much of what I discuss in this chapter, such as the MVP pattern and the service locator, is also recommended by the Microsoft Patterns & Practices group. You’ll also use some of the tools and services that the Microsoft Patterns & Practices group has built to allow for more maintainable and testable code.

13.1. Design patterns

Design patterns are an abstract term, and some developers love using them—and some don’t. Design patterns have evolved over time, and some are tied to specific technologies whereas others are generic. Because this chapter is about design patterns and specifically the MVP pattern (which I discuss in the next section), this section covers the key features required to successfully implement the MVP pattern. One feature, loose coupling, makes application component implementations less dependent on one another. Loose coupling is important for dependency injection, a method used to insert dependency objects during runtime.

13.1.1. What are design patterns?

Software design patterns are guidelines and templates that describe how to solve a problem. Design patterns aren’t a new thing; they’ve been around since the early ages of software engineering. A design pattern provides a proven and tested pattern for use when architecting and developing applications. Each design pattern tries to solve one or more problems and can be technology specific. It’s important to understand that a design pattern isn’t a component that you use or include in your application. A design pattern is more of a guideline on how to write the code. Design patterns start from different approaches. Some focus on the code’s structure whereas others focus on the application’s behavior. The naming conventions and terms used in design patterns are also a common language among developers, which makes it easy to discuss and document systems without going into details.

Design patterns offer several benefits when you’re building and designing software. The reuse of the same pattern within a solution helps you understand the solution design, and it allows for better collaboration because everyone on the team is aware of the methodology.

As I mentioned earlier, many SharePoint developers generally haven’t used software design patterns when building SharePoint applications. The lack of tools supporting a good development environment has put the focus on other things instead. Until recently, there has been no guide or official best practices documentation in this area for SharePoint development. The Microsoft Patterns & Practices group only mentioned SharePoint in a few pages in the Microsoft Application Architecture Guide, 2nd Edition (Microsoft Press, 2009). Since then, they’ve expanded their guidance for SharePoint and now have documentation, sample applications, and libraries.

 

Microsoft Patterns & Practices group

The Microsoft Patterns & Practices group is a team of experts and architects from Microsoft and other external organizations who focus on guidance and practices for developers. They continuously build and improve guidance, documentation, and sample implementations for Microsoft technologies.

The Patterns & Practices group is currently on their second SharePoint guide. You can find more information about this group at http://msdn.microsoft.com/practices/ and http://spg.codeplex.com.

 

13.1.2. Loose coupling

Several design patterns are based on loosely coupled objects. A loosely coupled system refers to a system where the objects and components aren’t directly dependent on one another. Loosely coupled objects are connected through an interface; the dependent class uses the interface to communicate to the concrete services. The opposite of a loosely coupled system is a tightly coupled system. Figure 13.1 shows a tightly coupled application where ClassA directly calls ClassB. There’s no way to replace or edit ClassB without recompiling and changing the system.

Figure 13.1. In a tightly coupled application, the classes are directly referencing each other. This makes the classes dependent on each other and makes it harder to replace classes and layers.

Tightly coupled systems are hard to test, change, and maintain because of the dependencies between the components. It’s also harder to build tightly coupled systems in teams and to split the systems into separate parts or domains.

In a loosely coupled system, ClassA doesn’t directly depend on ClassB. Instead, it uses a contract or an interface that defines the coupling. Figure 13.2 shows how ClassA depends on an interface, in this example, IService. This interface is used by both ClassB1 and ClassB2, which can be hosted in the same solution or in another one. ClassA doesn’t know anything about the implementation of ClassB1 or ClassB2. You can edit or replace ClassB1 or ClassB2 and even add new objects that implement the IService interface without recompiling ClassA.

Figure 13.2. In loosely coupled systems, the dependent class uses an interface to communicate with its services. This arrangement allows for easier updates of the services, even during runtime, and a clear separation of layers in the application.

Changes to the IService interface would require that you modify all classes. This is where planning and specification become important. Building loosely coupled systems tends to involve more planning but it does allow for easier management.

Loosely coupled systems are modular and simple to test. Because the objects don’t directly reference one another, you can isolate them for unit-testing. This testing method is also known as white-box testing. Unit-testing is focused on testing the object itself and not how it interacts with other objects. This approach allows for a more agile development process, and you can apply practices such as test-driven development (TDD), where you start writing the unit-tests before you implement the object itself. The opposite of white-box testing is black-box testing, where you test the whole system without any knowledge of the internals of the system.

13.1.3. Dependency injection

Dependency injection has become one of the most popular patterns when building loosely coupled systems. Because the loosely coupled system uses an interface as the contract for its services and modules, you can inject the implementation you want to use at runtime. The best way to describe dependency injection is by an example. Assume you have an interface that describes a car engine:

public interface IEngine {
    int GetSpeed();
    void IncreaseSpeed();
    void DecreaseSpeed();
}

This IEngine interface describes the functionality of the car engine but not how it works, how fast it accelerates, and so forth. An implementation of an engine would derive from the IEngine interface like this:

Different cars have different engines, which means that you can have several implementations of the IEngine interface . A fast car could be implemented as follows:

public class FastCar {
    readonly IEngine _engine;
    public FastCar() {
        _engine = new FastEngine();
    }
    public void Start() {
        while(_engine.GetSpeed() < 100) {
            _engine.IncreaseSpeed();
        }
    }
}

In the constructor of the FastCar class, the FastEngine implementation of the IEngine interface is injected. That way, you provide a great deal of flexibility to use different engines using the same car implementation by just changing the constructor. It’s worth mentioning here that the private engine declaration is immutable. Set the private engine variable as readonly, which means that it can only be set during the class construction.

 

Tip

If you’re interested in reading more about designing large testable and modular applications, check out Dependency Injection, Design Patterns Using Spring and Guice, by Dhanji R. Prasanna (Manning, 2009).

 

13.2. The Model-View-Presenter pattern

There’s one design pattern that fits nicely into Web Part development more than others: the Model-View-Presenter (MVP) pattern. This pattern has been used since the early 1990s. In 2006, Martin Fowler split MVP into two separate patterns: the Passive View and the Supervising Controller. The MVP term is still widely used and implies one of the two updated patterns.

Building Web Parts using the MVP pattern differs from what you may be used to. If you’ve been in the ASP.NET business, you might be familiar with the Model-View-Controller (MVC) pattern, from which MVP is derived. An MVP-based Web Part requires additional coding and a separation of the business logic from the WebPart class implementation. That way, the work can be distributed among team members, and it allows for better testing of the layers independently.

13.2.1. The Passive View pattern

The MVP pattern is a user interface design pattern that decouples the user interface (View) from the business logic (Presenter) and from the domain/data layer (Model). The different pieces can be tested individually with or without one another and optionally using mock (fake) objects.

The MVP pattern not only makes unit-testing easier but also facilitates code reuse. For instance, the same Model and Presenter can be used for different user interfaces, such as a Web Part, a page, or a Silverlight application. In addition, decoupling enables different developers to build different pieces, independently. That way, you can use the appropriate type of developer for the right task; user interface developers can build the views, and so on.

The basics of the MVP pattern is that the View is responsible for the user interface and is defined using an interface that acts as a contract for the Presenter. All actions in the user interface are forwarded to the Presenter, which is responsible for updating the View through the interface. The presenter uses the Model to access the domain, data, or underlying systems.

The Passive View variation of the MVP pattern is the cleanest version of the two. As you can see in figure 13.3, the View forwards user actions to the Presenter, which updates the View through the interface. The Presenter uses information from the Model to update the View. The Presenter optionally responds to events fired in the Model if the Model is updated by someone other than the Presenter. The View is totally unaware of the Model.

Figure 13.3. The Passive View design pattern divides the application into three layers; the Presenter stays in the middle updating the View with information and data from the data Model.

This decoupled pattern allows you to test the Presenter and Model independently. As always, the user interface is difficult to unit-test, but the Presenter can be replaced with a mock object that makes it easier to manually test the interface.

 

Tip

To test the user interface of a SharePoint application you can use the Coded-UI tests available in Visual Studio Premium or Ultimate editions.

 

Compared to a user interface component built using a single class, this pattern introduces a higher level of complexity, both in number of files and method calls. But at the same time, early testing and a clear separation of layers means that errors are discovered earlier in the process.

13.2.2. The Supervising Controller pattern

Another variation of the MVP pattern is the Supervising Controller. It differs from the Passive View in that the View is allowed to do simple data binding to the Model but isn’t allowed to make changes to it (see figure 13.4).

Figure 13.4. The Supervising Controller pattern is similar to the Passive View pattern but allows the View to make simple calls and data binding to the Model.

The Supervising Controller makes the Presenter easier to implement because it doesn’t need to move all data from the Model to the View. One of the main goals for this variation is to make the coding easier, but it reduces the testability of the solution. It’s also sometimes less difficult to maintain solutions built using the Supervising Controller because smaller changes in the user interface don’t require that the Presenter be modified.

13.2.3. MVP and Web Parts

The MVP design pattern is a perfect match for Web Parts. The way that the Presenter is communicating with the View allows for a clear separation of the business logic and the interface components. Reusing code is also a key factor here. By using the same Model and/or Presenter for several Web Parts, you’ll find the development cycle is faster and more failsafe.

I’ll show you how to build a Web Part using the Passive View variant of the MVP pattern for a Web Part that lists all the available Lists in the current site. This is a very simple Web Part that uses a single Web Part class and just a few lines of code. To show you the benefits of using the Passive View pattern, I’ll explain each part of the code. Finally, I’ll take the pattern one step further by decoupling the Model and preparing it for isolated testing and for use with a service locator.

Building an MVP Web Part

To build a Web Part, you use the MVP pattern in Visual Studio 2010 and the SharePoint Developer Extensions. You can choose to build a sandboxed Web Part or deploy it as a farm solution. The Web Part that you’ll build next will display all the available lists within a site and provide a link to the default view of each one, as shown in figure 13.5.

Figure 13.5. A Web Part based on the Passive View pattern displaying links to all lists within a SharePoint site

The View

The first thing you’ll define after adding a new Web Part to your solution is the View interface. This interface will be the contract that the Presenter uses to update the View. The View interface, IListsView, is implemented as follows:

public interface IListsView {
    IEnumerable<ListInfo> Lists {
        get;
        set;
    }
}

The Lists property defined in the interface returns an enumerator with ListInfo objects. The ListInfo object is a class that contains the name (Title) of a list and its default view URL (Url). The reason that a custom class is used instead of the SharePoint SPList object is that this approach decouples the View and the Presenter from SharePoint and allows for easier testing. The ListInfo class is defined like this:

public class ListInfo {
    public string Title {
        get;
        set;
    }
    public string Url {
        get;
        set;
    }
}
The Model

The Model can be implemented in several ways; it can be a SharePoint object, a data context, or something else. For instance, the Model could be the SPListCollection object in this example. But the best solution is to create a service model that encapsulates the data layer. In your Lists Web Part, a service class called ListsService is created that provides the operations needed to the Presenter:

class ListsService {
    public IEnumerable<ListInfo> GetLists() {
        SPWeb web = SPContext.Current.Web;
        List<ListInfo> listInfo = new List<ListInfo>();
        foreach (SPList list in web.Lists) {
            listInfo.Add(new ListInfo() {
                Title = list.Title,
                Url = list.DefaultViewUrl
            });
        }
        return listInfo;
    }
}

This Model implementation provides a method called GetLists, which returns a collection of ListInfo objects. The Presenter uses this method to set the state of the View.

The Presenter

The Presenter is the glue that connects the data provided by the Model to the View. In the MVP pattern, the Presenter interacts with the View implementation through the interface. You create the Presenter like this:

public class ListsPresenter {
    protected readonly IListsView _view;

    public ListsPresenter(IListsView view) {
        _view = view;
    }
    public void LoadLists() {
        ListsService service = new ListsService();
        _view.Lists = service.GetLists();
    }
}

The Presenter contains a reference to the IListsView interface through a protected variable. The variable is set as readonly, which means that it’s immutable and can only be set in the constructor of the class. The constructor of the Presenter accepts the View interface to keep the reference. This method of injecting a dependency is called dependency injection; specifically this is constructor injection because you insert the dependencies in the constructor. The LoadLists method, which is the business logic, uses the service class (Model) to retrieve the lists and finally updates the View through the internal property.

You can define all the code classes and interfaces in the same or a separate assembly. It all depends on how you’ll reuse the code in your solution.

The Web Part

In this MVP implementation, the Web Part is the implementation of the View. That is, the Web Part class will inherit from the IListsView interface like this:

public class SiteListsWebPart : WebPart, IListsView

The IListsView interface contains a single property, Lists. This property needs to be implemented in the Web Part:

public IEnumerable<ListInfo> Lists {
    get;
    set;
}

Then all that’s left is to build the user interface. Do so using the CreateChildControls method of the Web Part:

protected override void CreateChildControls() {
    ListsPresenter presenter = new ListsPresenter(this);
    presenter.LoadLists();

    foreach (ListInfo listInfo in this.Lists) {
        this.Controls.Add(new HyperLink() {
            Text = listInfo.Title,
            NavigateUrl = listInfo.Url
        });
        this.Controls.Add(new LiteralControl("<br/>"));
    }
}

First, this code creates an instance of the ListsPresenter and passes the Web Part (the View) as an argument to the constructor. Then the LoadLists method of the Presenter is called. Because the Presenter is responsible for updating the View, it will populate the Lists property of the Web Part. Finally, the interface is built by iterating over the Lists collection objects, which creates the list of links to the lists.

From a practical perspective, you can now see how you can benefit from using this pattern. For instance, you can have several developers building the various parts. The person building the View can use a fake Presenter to avoid waiting for completion of the real Presenter. The developer building the Presenter can use the same approach with the Model. The different parts also are decoupled, so you can unit-test most of the code.

Decoupling the Model From the Presenter

The current design ties the Model to the Presenter because the LoadLists method instantiates the Model and uses the methods directly. By changing the Model class to inherit from an interface that expresses the Model’s functionality, you can decouple the implementation of the Model from the Presenter:

public interface IListsService {
    IEnumerable<ListInfo> GetLists();
}

Once that’s done, you edit the ListsService class definition so that it inherits from the new Model interface as follows:

class ListsService : IListsService

Now there’s a contract for how the Model is implemented, through the interface, and you can use dependency injection to provide multiple Models to the same Presenter and View. For instance, the current ListsService Model returns all lists within a site. If you need another Model, called LibraryService, that returns all document libraries, you can create a new Model implementation that has a GetLists method like this:

public IEnumerable<ListInfo> GetLists() {
    SPWeb web = SPContext.Current.Web;
    List<ListInfo> listInfo = new List<ListInfo>();
    foreach (SPList list in web.GetListsOfType(SPBaseType.DocumentLibrary))
    {
        listInfo.Add(new ListInfo() {
            Title = list.Title,
            Url = list.DefaultViewUrl
        });
    }
    return listInfo;
}

You must modify the Presenter implementation to support the dependency injection. Simply add a new local variable to the Presenter class and modify the constructor to support injection of the Model:

class ListsPresenter {
    protected readonly IListsView _view;
    protected readonly IListsService _model;

    public ListsPresenter(IListsView view) {
        _view = view;
        _model = new ListsService();
    }

    public void LoadLists() {
        _view.Lists = _model.GetLists();
    }
}

The IListsService is stored as an immutable variable in the Presenter class. The constructor is modified so that it sets the injected View and then creates one of the Model implementations. Finally, the LoadLists method is modified to use the Model interface instead of creating a Model class, as the previous implementation did. By using this pattern with decoupled objects, you can easily replace, change, or duplicate almost any part of the Web Part without affecting the other parts. Using the Visual Studio 2010 class diagram designer, the solution looks like figure 13.6.

Figure 13.6. The Class Diagram designer in Visual Studio 2010 is a great tool to use when working with decoupled objects to visualize the system design.

13.3. SharePoint Service Locator

In a fully decoupled system, you want to write code that isn’t dependent on the concrete implementation of the classes. To accomplish this goal, you can use a repository that stores mappings between the service interfaces and the service implementations. A service locator is such a repository; it handles registrations of types and maps them to one or more implementations.

The Microsoft Patterns & Practices group has created a base service locator implementation and a specific service locator for SharePoint. The SharePoint Service Locator allows developers to store different type-mappings at different levels in SharePoint, such as farms or site collections. That way, your service can use different Models or Views depending on where it’s located or depending on what features have been enabled at the current level.

13.3.1. Service locators

The problem with this implementation of the Web Part is that you’re referencing a Model implementation in the code of the Presenter. To switch to another Model, the Web Part must be compiled and redeployed to SharePoint—not a very flexible solution. It’s also hard to test the Presenter in isolation using unit-tests because it depends on the Model, as you can see in figure 13.7. If you’d like to dynamically switch between different Model implementations, you need to provide logic for that.

Figure 13.7. Using multiple services for a class requires custom code that handles the request for the correct service during runtime.

A service locator is a central repository that contains references to services and the different implementations of the services. Services are registered in the service locator, and classes can query the service locator for a specific service to get an instance of it, as you can see in figure 13.8.

Figure 13.8. Using a service locator allows for dynamic changes during runtime of services. The service locator is a shared service within the application that handles registration and location of services.

Services are registered in the service locator using an interface or a key-value and a reference to its implementation. The classes using the service locators use the interface or key to query for the implementation of the service and the service locator decides which implementation to use at runtime.

The service locator preferably has a persistent storage but can also be populated during application initialization. The locator allows the application to locate a service during runtime and use it. Adding new services might not always require that the code be recompiled because the classes only depend on an interface or a key.

13.3.2. Use the SharePoint Service Locator

The SharePoint Service Locator provides functionality to register a service using an interface and an optional key value and functionality to locate an implementation of a registered interface. In this section, you’ll learn how to modify the Web Part you built using the MVP pattern to use the locator to find the implementation of the Model.

Adding SharePoint Service Locator References

To use the SharePoint Service Locator, you need to download its implementation from the Patterns & Practices group SharePoint Codeplex site at http://spg.codeplex.com/. The implementation contains the source code required to build the assembly for the locator. Once you’ve built the SharePoint Service Locator, you’ll need to add references to the assemblies in your SharePoint project. Right-click References in the Solution Explorer in Visual Studio and select Add Reference. Browse to location where the SharePoint Service Locator assemblies are located and choose to add them. The files are called Microsoft.Practices.ServiceLocation.dll and Microsoft.Practices.SharePoint. Common.dll. The first of the assemblies is a general service locator implementation. The second contains the SharePoint-specific implementation as well as other useful components for SharePoint development, such as logging and configuration.

 

Note

The SharePoint Service Locator can be used in the sandbox, but then services can only be located from the site collection level. To provide access to farm-level registered services, a proxy solution is provided as an alternative.

 

To include the referenced assemblies in the SharePoint Solution package, you must add them to the package manifest. Do so by editing the package in Visual Studio and selecting the Advanced tab. Click Add > Add Existing Assembly in the designer to open a dialog box. Here you can select an assembly and click OK to add the assembly to the package. Add both of the referenced assemblies. Make sure that the Deployment Target is set to GlobalAssemblyCache. These assemblies will now be registered in the Global Assembly Cache when the solution is deployed in the farm.

 

Tip

If you’re going to use the SharePoint Service Locator in many solutions, create a separate farm solution that registers the locator in the Global Assembly Cache.

 

Registering the Model with the Service Locator

The services in the SharePoint Service Locator are typically registered when a feature is installed or activated. The SharePoint Service Locator supports registration of services at both the site collection level and the farm level. A site collection–registered service has precedence over a farm-registered service.

Updating the Presenter

To decouple the Presenter from the Model, you have to modify the constructor of the Presenter. You do this by modifying the constructor and adding a second constructor to the ListsPresenter class:

public ListsPresenter(IListsView view): this (view, new ListsService()) {
}

public ListsPresenter(IListsView view, IListsService model) {
    _view = view;
    _model = model;
}

The first constructor calls the second constructor but still creates an instance of the ListsService object. This constructor is kept so that the View implementation doesn’t break. The second constructor takes both the View and the Model as parameters.

Registering the Model

You must register the Model in the SharePoint Service Locator before using it. I recommend that you use a Feature receiver to do this. Registering farm-scoped features requires that they be registered using a Farm Administrators account. This means that you can’t enable and disable the features using the web user interface in a site collection. You can perform farm-scoped registrations in one of three ways:

  • Using hidden features enabled by PowerShell
  • Using the FeatureInstalled/FeatureUninstalling events of the Feature event receiver
  • Using a farm-scoped feature

To register the ListsService Model for the Web Part, add a new event receiver to the Web Part feature. Then implement the FeatureInstalled and FeatureUninstalling like this:

public override void FeatureInstalled(
    SPFeatureReceiverProperties properties) {

    IServiceLocator serviceLocator =
             SharePointServiceLocator.GetCurrent();
    IServiceLocatorConfig serviceLocatorConfig =
        serviceLocator.GetInstance<IServiceLocatorConfig>();

    serviceLocatorConfig.
        RegisterTypeMapping<IListsService, ListsService>();
}

public override void FeatureUninstalling(
    SPFeatureReceiverProperties properties)

    IServiceLocator serviceLocator =
             SharePointServiceLocator.GetCurrent();
    IServiceLocatorConfig serviceLocatorConfig =
        serviceLocator.GetInstance<IServiceLocatorConfig>();

    serviceLocatorConfig.RemoveTypeMappings<IListsService>();
}

To register the service with the locator at the farm level, a user with farm administrator privileges must register the service during the installation of the solution. Both FeatureInstalled and FeatureUninstalling use the static method GetCurrent of the SharePointServiceLocator object to retrieve the current service locator. The service locator configuration object is also a service registered with the service locator, and you locate it by using the GetInstance method using the IServiceLocatorConfig interface. When an instance of the service locator configuration object is retrieved, the RegisterTypeMapping method is used to register the ListsService. This is done by providing the interface of the service and an implementation of the service. The unin-stall method removes all registrations of a specific service using the RemoveTypeMappings method.

Using the Service Locator in the View

The only task remaining is to use the service locator in the implementation of the View and inject the Model into the Presenter. Modify the CreateChildControls method of the Web Part to use the SharePoint Service Locator:

protected override void CreateChildControls() {
    IServiceLocator serviceLocator = SharePointServiceLocator.GetCurrent();
    IListsService service = serviceLocator.GetInstance<IListsService>();

    ListsPresenter presenter = new ListsPresenter(this, service);
    presenter.LoadLists();

    foreach (ListInfo listInfo in this.Lists) {
        this.Controls.Add( new HyperLink() {
            Text = listInfo.Title,
            NavigateUrl = listInfo.Url
        });
        this.Controls.Add(new LiteralControl("<br/>"));
    }
}

Just as in the Feature receiver, you retrieve the SharePoint Service Locator using the GetCurrent method. Rather than retrieving the configuration service, the configured mapped type for IListsService is retrieved using the GetInstance method. The service instance is injected to the constructor of the ListsPresenter together with the current Web Part. That is, both the Model and the View are injected into the Presenter.

If you deploy the Web Part and add it to a page, you’ll see that it looks exactly the same as before. You haven’t changed the Web Part’s appearance—you’ve just decoupled the Presenter from both the Model and the View and made it possible to switch to different implementations of the Model.

Replacing the Model at Runtime

To add a second Model implementation, replacing the previous one, and add that as a service to the service locator, you add a new feature to the project. The feature must be scoped to Farm, if the service is to be registered at farm level, to avoid access denied exceptions. Add a Feature receiver to the new feature and, in the FeatureActivated method, register the LibraryService, which you created earlier. Instead of displaying all lists, the Web Part shows only document libraries. Figure 13.9 shows how the Web Part might look like when the LibraryService is used instead of the ListsService.

Figure 13.9. By supplying an alternative Model to the Site Lists Web Part, you modify its appearance to show libraries instead of lists without editing the View or Presenter classes.

You use the RegisterTypeMapping to register the new service. The registration will replace any previous type mapping:

serviceLocatorConfig.RegisterTypeMapping<IListsService, LibraryService>();

This code replaces the current type mapping in the service locator with the new LibraryService. In the FeatureDeactivating method, add the following to restore the original service implementation:

serviceLocatorConfig.RegisterTypeMapping<IListsService, ListsService>();

When the updated solution is deployed to SharePoint, the farm-scoped feature is automatically activated and the document libraries are shown. To display the lists again, the farm-scoped feature has to be deactivated in Central Administration or via PowerShell. The SharePoint Service Locator caches all type mappings, and the application pools need to be recycled. You can do this by executing the IISRESET command.

Figure 13.10 shows how the Visual Studio class designer visualizes the Web Part, interfaces, and services after adding the new Library service. Notice how the Presenter now allows for injection of the Model through its constructor.

Figure 13.10. Adding the injection of the Model into the Presenter’s constructor allows you to implement multiple Models to be used by the same Presenter and View.

If you’d like to specify which model to use during runtime, the SharePoint Service Locator supports naming the registered interfaces. You can then use the GetInstance method of the service locator to retrieve the instance using the interface and the registered name. The service locator also contains a method for retrieving all registered services for a specific interface called GetAllInstances. You could use this method to create a Web Part where the end user chooses, via an Editor Part, which service to use.

 

Tip

To recycle the application pools from the Visual Studio 2010 interface, install the CKS:DEV extensions using Visual Studio 2010 Extensions Manager. Then choose Tools > CKSDEV > Recycle All SharePoint Application Pools to recycle the application pools. Download it through the Visual Studio Extension Manager.

 

The farm-scoped feature can now be used to switch between the two Model implementations. While working in teams, this can be useful. For instance, one developer might be working on the Presenter and View and another developer on the Model. The developer working with the Presenter implementation can then use a mock Model service until the final Model service is complete.

 

Microsoft’s Unity Application Block

Microsoft’s Unity Application Block is a dependency injection container that has become widely popular. It’s powerful but can be quite complex for beginners. Unity is supported on different platforms such as web, desktop, and Silverlight. If you’re familiar with the Unity Application Block or if your company uses Unity in other applications, it might be good idea to use Unity in your SharePoint projects as well. The SharePoint Service Locator GetCurrent method returns IServiceLocator, which can be replaced with any custom service locators, such as a Unity service locator.

You can download Unity at http://unity.codeplex.com/.

 

13.4. Testing Web Parts

Just as with design patterns, the SharePoint world hasn’t used automatic testing to the same degree as developers using other technologies. It’s very hard to test components and applications automatically in SharePoint. And it’s even harder to test the components outside the SharePoint environment because most components rely on the environment.

By building loosely coupled applications, you’ll find it much easier to take the application or specific components out of their original context and test them. Visual Studio contains tools and templates for unit-testing, and I’ll show you how to use these tools to test the Web Part you’ve built in this chapter.

13.4.1. Unit-testing

Unit-testing is a method in which you test the smallest testable piece of code, called a unit. The foundation for unit-testing is that by having small tests that independently test parts of the code you’ll find errors and mismatches early in the software development cycle. Not only do unit-tests examine the code, but they can also serve as specifications of the code and are often used as a check for requirements. For instance, test-driven development starts with writing the unit-test before writing the code that’s going to be tested, which also requires you to have the basic requirements and functional specification agreed upon before starting.

Unit-testing also allows for better refactoring of the code and lets you track any changes that would potentially break your solution when you’re modifying the source code. Keeping the unit-test small enables the tests to run quickly so that they can be included in all builds without slowing down the developers.

Unit-testing relies heavily on mock or fake objects during the tests. Mock objects are simulated objects that mimic the behavior of the real objects. For instance think of a data model object that reads from a SharePoint list and returns the title of the list; a mock object for this model object could return a hardcoded string for testing purposes. By using loosely coupled objects and dependency injection, you’ll find it easier to create the tests.

13.4.2. Creating a test project

Visual Studio 2010 has built-in support for creating test projects containing automatic and manual test items. The test tools in Visual Studio contain a complete suite for building tests and analyzing those results, including code coverage, profiling, and test impact.

The Web Part that you’ve been building in this chapter is designed for testability, and to create tests for it you need to add a new test project to the solution. Do so by creating a new project in Visual Studio, selecting the Test Project template, and adding it to the current solution. A default Unit-test project item is added to the project; you can remove this test item.

You can add many types of test project items to a test project, as shown in figure 13.11. Most of the project items are focused on unit-testing, and you can create unit-tests manually from scratch or use a wizard. You can even combine your unit-tests into a composite test. Not everything can be tested using unit-tests, and there are project items for recording actions to test user interfaces.

Figure 13.11. Visual Studio 2010 allows developers and testers to select from many different test project items, ranging from custom tests, to unit-tests, to fully automated interface tests.

 

Note

Not all types of tests are available in all editions of Visual Studio 2010. For more information, see http://www.microsoft.com/visualstudio/products.

 

13.4.3. Mock objects

Before creating the tests for the Web Part, you need to create the mock objects. Mock objects serve as fake objects that are injected into the code to be tested. For instance, the ListsService class (the Model) used by the ListsPresenter class (the Presenter) relies on the code running inside a SharePoint environment. Because the Web Part is designed using dependency injection, this is an easy task to perform. Instead of injecting the ListsService class when testing the ListsPresenter, you can inject a mock object inheriting the IListsService interface. The mock object, called MockModel, is added to the test project and implemented like this:

class MockModel: IListsService {
    public IEnumerable<ListInfo> GetLists() {
        List<ListInfo> dummy = new List<ListInfo>();
        dummy.Add(new ListInfo(){
            Title = "Title 2",
            Url= "http://test1/"
        });
        dummy.Add(new ListInfo(){
            Title = "Test 2",
            Url= "http://test2/"
        });
        return dummy;
    }
}

The MockModel implements the IListsService interface and provides an implementation of the GetLists method. In the GetLists method, a fake list of ListInfo objects is created.

The same is done for the View of the Web Part. A mock object called MockView that inherits from the IListsView interface is also added to the test project:

class MockView: IListsView {
    public IEnumerable<ListInfo> Lists {
        get;
        set;
    }
}

All this mock object requires is that an implementation of the Lists property be done. These two mock objects allow for testing the complete implementation of the Presenter.

Unit-testing the Model of the Web Part—that is, the ListsService or LibraryService—is harder. You can’t create fake objects of the SPWeb or the SPList objects. Fortunately, certain products on the market allow for mocking SharePoint objects that during runtime of the tests replace the SharePoint objects with fake objects. Microsoft Research has released a power tool for Visual Studio called Pex and Moles. This is an isolation and white-box testing framework in which Pex automatically generates unit-tests. Moles is an advanced framework that uses the code profiler API to intercept calls to any dependencies and then replace that dependent object with a fake object. You can download Pex and Moles from the Visual Studio Extension Manager and read more about them at http://research.microsoft.com/pex.

13.4.4. Test the Web Part

By now, everything is set up for creating the unit-tests of the Web Part. To add a unit-test using the Create Unit-tests wizard, select Add > Unit-test on the test project. In the dialog window that appears, select the class or classes for which you want to create automatic tests, as shown in figure 13.12, and click OK.

Figure 13.12. The Create Unit-tests wizard generates stubs for the test methods, to which you then add the test logic.

For this example, on the Create Unit-tests screen select the ListsPresenter class, which is the class that will be used for this test case. Once you click OK, the wizard will add a new file to the test project called ListsPresenterTest.cs. This new file contains the stub methods for the unit-tests. For the ListsPresenter, the test class will contain three tests: two for the two constructors and one for the LoadLists method.

Each test method is suffixed with Test and has the TestMethod attribute. The TestMethod attribute allows Visual Studio to pick up all unit-tests within the classes and project and identify them as tests.

Let’s take a look at the first constructor test. When the wizard creates the test, it looks like this:

[TestMethod()]
public void ListsPresenterConstructorTest() {
    IListsView view = null; // TODO: Initialize to an appropriate value
    IListsService model = null; // TODO: Initialize to an appropriate value
    ListsPresenter target = new ListsPresenter(view, model);
    Assert.Inconclusive("TODO: Implement code to verify target");
}

To complete the test, you have to modify this method so that it tests the constructor of the ListsPresenter. The View and the Model interfaces that are going to be injected into the ListsPresenter constructor are defined as null; these two have to be initialized with the mock objects. Then the ListsPresenter is created with these mock objects, and the result has to be evaluated. You must change the assertion to verify that the returned object from the constructor isn’t null. After you make these changes, the test should look like this:

[TestMethod()]
public void ListsPresenterConstructorTest() {
    IListsView view = new MockView();
    IListsService model = new MockModel();
    ListsPresenter target = new ListsPresenter(view, model);
    Assert.IsNotNull(target);
}

Now, the test method is ready for testing. The same procedure has to be repeated for the second constructor test and the test of the LoadLists method. The second constructor test is similar to the first one, and you should change the LoadLists test to this:

This test of the LoadLists method creates the Presenter using the View and Model mock objects. As you can see, the first three lines of the test define what’s tested in the constructor test. A unit-test should test only a single method, if possible, and because there’s already a test for the constructor, it’s not tested here. After calling the LoadLists method (which is the method that’s tested), the Lists object of the MockView object is verified so that it’s not null. Remember the Presenter object filled the View using the Model. The MockModel that was built earlier created a list containing two items, and they’re also tested as the last part of the test.

It’s now time to run the tests. Do so by selecting Tests > Run > All Tests in Solution in Visual Studio. Visual Studio will open the Test Results window, and you can follow the test’s progress. Once all tests are finished, you can see the results in the Test Results window, as shown in figure 13.13, and eventually check and fix failed tests. In this example, all tests passed successfully.

Figure 13.13. Use the Test Results window to inspect the status of the test runs and to get more information about failed tests.

If you have an edition of Visual Studio 2010 (such as Visual Studio 2010 Ultimate) that supports code coverage, you can enable that feature to inspect the parts of the source that were tested. Figure 13.14 shows that the current tests fully cover the ListsPresenter class in the Web Part.

Figure 13.14. The Code Coverage tool in Visual Studio lets you see exactly what parts of the code executed during the tests.

13.5. Summary

If you’re new to design patterns and unit-testing, I hope that this chapter opened your eyes to the possibilities. Many developers put testing and design patterns on the lowpriority list. But you should now realize that it’s not as hard as it first looks and that testability should be on your high-priority list. By using the MVP pattern, you make it easier to test your code and you can test large portions of it using unit-tests. If the Web Parts are continuously tested, you get fewer errors and bugs, which means you can focus on creating new stuff instead of fixing old problems.

The SharePoint Service Locator used in this chapter allows you to have different backends of your Web Parts, which leads to high reusability. It also enables you to put the right person on the right task; the GUI expert can build the user interface and the SharePoint developers can focus on the data model or logic. If you like the SharePoint Service Locator, consider looking into the other SharePoint assets provided by the Patterns & Practices group, such as the Hierarchical Configuration Manager and the SharePoint Logger.

In the next chapter, I’ll show you how to connect your Web Parts. Web Part connections allows you to build composite applications consisting of multiple Web Parts that can communicate with each other.