Application Foundations for SharePoint 2010
There is a world of difference between simply making your code work and writing production-quality applications. Before you look at specific areas of SharePoint functionality in greater detail, it's important to ensure that your solutions are built on solid foundations. This chapter looks at how you can improve the quality of your code across the entire spectrum of SharePoint functional areas. It also introduces some of the reusable components that are included in the SharePoint Guidance Library to help you develop better solutions.
So what makes good code? Performance and stability are obviously at the top of the list. However, when you develop code for enterprise-scale applications, other concerns become increasingly important:
- Testability. Can you test your classes in isolation? If your code is tightly coupled to a user interface, or relies on specific types, this can be challenging.
- Flexibility. Can you update or replace dependencies without editing and recompiling your code?
- Configuration. How do you manage configuration settings for your solution? Will your approach scale out to an enterprise-scale deployment environment?
- Logging and exception handling. How do you log exceptions and trace information in the enterprise environment? Is your approach consistent with that of other developers on the team? Are you providing system administrators with reliable information that they can use to diagnose problems effectively?
- Maintainability. How easy is it to maintain your code in a code base that is constantly evolving? Do you have to rewrite your code if a dependent class is updated or replaced?
This topic is designed to provide you with guidance on how to address these challenges when you develop enterprise-scale solutions for SharePoint 2010. The content does not provide an introduction to SharePoint development—if you're looking for guidance on getting started, visit the SharePoint Developer Center on MSDN. This content is for developers with some experience with the SharePoint product suite who want to improve the quality and robustness of their SharePoint applications through best practice use of design patterns.
The SharePoint Guidance Library includes reusable components and utility classes that can help you to address each of these challenges:
- The SharePoint Service Locator can help you to develop testable, modular code, by enabling you to decouple your code from dependencies on external types.
- The Application Setting Manager can help you to manage configuration settings, by providing a robust, consistent mechanism that you can use to store and retrieve configuration settings at each level of the SharePoint hierarchy.
- The SharePoint Logger can help you to log exceptions and trace information in a consistent, informative way, by providing easy-to-use utility methods that write to the Windows Event log and the ULS (SharePoint Unified Logging Service) trace log.
Note
The August 2009 Developing SharePoint Applications release, which targets the SharePoint 2007 platform, covers many areas related to quality and supportability in greater depth. You can review this guidance in Considerations for Enterprise Scale Applications on MSDN. This release focuses on a subset of fundamentals for managing testability, flexibility, application configuration, and logging in SharePoint 2010, together with the reusable components that can help you in these areas.
Testability and Flexibility
When you write a unit test, you are aiming to isolate a piece of code in order to test it with known inputs. You typically need to substitute dependencies—such as external code, data sources, and the user interface—with fake implementations that provide the specific conditions that you want to test. These fake implementations are referred to by various names, but most often, they are known as mocks or stubs.
When you write flexible, modular code, you are also aiming to isolate your code from the implementation details of external classes, data sources, and the user interface. Ideally, you should be able to amend or replace dependencies without editing and recompiling your code. As such, testability and flexibility go hand in hand. To write fully testable code is to write flexible, pluggable code.
You can use a combination of design patterns to isolate your code in this way.
- The Service Locator pattern allows you to request an implementation of an interface without knowing the details of the implementation. As such, you can replace dependencies with alternative implementations or mock implementations without editing or recompiling your code.
- The Model-View-Presenter (MVP) pattern allows you to isolate the business logic in your application from the user interface. As such, you can test the business logic in isolation. You can also make the business logic easier to understand and maintain by removing user interface–specific implementation details.
- The Repository pattern allows you to isolate the data access code in your application from the business logic. You can use the Repository pattern to wrap any data source, such as a database or a SharePoint list. This allows you to test the data access code in isolation and to substitute the data access implementation to unit test your business logic.
The Service Locator pattern is particularly valuable in enterprise-scale applications because it decouples your code from all its dependencies. The advantages go beyond facilitating unit tests. This pattern makes the entire solution more modular and more flexible, because you can update and replace individual components without having to edit and recompile consumer classes. Just like the previous releases of the SharePoint Guidance Library, this release includes a SharePoint-specific implementation of the Service Locator pattern that you can use in your own solutions. For more information, see The SharePoint Service Locator.
When you start writing code for SharePoint applications with testing in mind, it is important to understand the difference between unit tests and integration tests. Unit tests isolate your code from all its dependencies and should run outside the SharePoint execution environment. Unit tests typically execute very quickly, allowing rapid iterations. They also allow you to test error conditions that would be hard to reproduce with actual SharePoint logic, such as a disk or database running out of space. On the other hand, integration tests follow later and test whether your code functions as expected in its target execution environment. In this case, integration tests run against the SharePoint 2010 APIs. For more information about unit testing and integration testing, see Testing SharePoint Solutions.
This release describes how to use a test framework named Moles, which is scheduled to ship with the next release of Visual Studio Power Tools. The Moles framework allows you to create mock objects for use in unit tests. For example, you can create mock SharePoint objects that allow you to run unit tests from outside the SharePoint execution environment. It also allows you to run integration tests directly against the SharePoint execution environment. For more information, see The Moles Framework.
Note
Previous releases of the SharePoint Guidance Library demonstrated the use of another third-party mocking product named TypeMock Isolator. TypeMock Isolator provides similar functionality using a behavior-driven approach. TypeMock also has a specific version of Isolator that targets the SharePoint APIs.
Configuration
Almost every application needs to store and retrieve configuration data of some kind, such as the location of lists that are shared between applications and other environment-specific variables. However, when you develop solutions for a platform like SharePoint 2010, it's not always obvious where you should store your configuration settings.
The first complicating factor is the hierarchical logical architecture of SharePoint. When you deploy a SharePoint application, you will typically scope your application to one of these logical levels—the server farm, the Web application, the site collection, or the site. At each of these levels, different mechanisms are available for the storage and retrieval of configuration settings. Other factors such as payload size, serialization, and security constraints will also affect your choice of storage mechanism.
You can use the following mechanisms to manage configuration information within the SharePoint environment:
- Web.config. You can add configuration data to the configuration file either declaratively or programmatically. This effectively confines your configuration settings to the Web application scope.
- Hierarchical object store. You can use the SPPersistedObject class to persist strongly-typed data at any level of the SharePoint hierarchy.
- Property bags. Each level of the SharePoint hierarchy exposes property bags, albeit with slightly different access mechanisms.
- Lists. You can persist configuration data to a SharePoint list. This effectively confines your configuration settings to the site collection scope or the site scope.
For more information about each of these storage mechanisms, together with the advantages and disadvantages of each approach, see the following resources on MSDN:
- Managing Application Configuration
- Managing Custom Configuration Options for a SharePoint Application
Because of the complexities in choosing and implementing an appropriate strategy for the storage of configuration data, the SharePoint Guidance team has developed a reusable component named the Configuration Manager. The Configuration Manager provides a consistent, strongly-typed mechanism that you can use to store and retrieve configuration settings in property bags at any level of the SharePoint hierarchy. The Configuration Manager also provides a hierarchical storage model, which allows you to override settings at different levels of the hierarchy. For example, if you have defined a configuration setting at the site collection level, you can override this setting for a specific site by adding the same configuration key at the site level. For more information, see the Application Setting Manager.
Logging and Exception Handling
When you develop an application for any platform, you must ensure that your application provides information about run-time issues to system administrators. In many cases, you will also want to record trace information so that developers can follow the execution of your application through key points in the logic. For general guidance on using event logs and trace logs for SharePoint applications, see Providing Application Diagnostics.
SharePoint 2010 includes enhanced functionality for logging and tracing. You can now throttle reporting to the Windows Event Log and the Office Server Unified Logging Service (ULS) trace logs by area and by category. Areas represent broad regions of SharePoint functionality, such as Access Services, Business Connectivity Services, and Document Management Server. Within each area, categories define more specific aspects of functionality. For example, the Document Management Server area includes categories named Document Management, Information Policy Management, and Records Center.
In addition to areas and categories, SharePoint 2010 makes substantial improvements to event correlation. Every trace log entry now includes a correlation ID that identifies all the events that correspond to a particular action, such as a user uploading a document. Administrators can use tools such as the ULS Viewer to filter the trace logs by correlation ID. The platform also provides a centralized logging database that allows you to consolidate diagnostic information and generate reports. SharePoint 2010 also includes a Health Analyzer tool that administrators can configure to actively monitor the system for error conditions and to address them where possible. For more information about these features, see Configuring Monitoring on TechNet.
The SharePoint Guidance Library includes a reusable logging component, the SharePoint Logger, that you can use in your SharePoint applications to write to the Windows Event log and the ULS trace logs. The latest release of the SharePoint Logger features support for the extended SharePoint 2010 logging functionality. For example, you can select areas and categories when you write to the event log or the trace logs, and you can create your own areas and categories for use in your applications. For more information, see The SharePoint Logger.
Using the Library in the Sandbox
The introduction of the sandbox execution environment in SharePoint 2010 posed some interesting challenges for the developers behind the SharePoint Guidance Library, because the sandbox environment imposes restrictions on many of the key functional areas. The latest release of the SharePoint Guidance Library includes enhancements that enable the library to run in the sandbox environment. Not all of the functionality will work in the sandbox, because there are certain limitations imposed by the environment that are unavoidable. The guidance library provides full-trust proxies that you can optionally install to enable configuration management and logging from sandboxed code. Full-trust proxy assemblies are deployed to the global assembly cache and expose full-trust functionality to sandboxed code that would otherwise be unavailable. There are three possible configurations you can use to access the guidance library functionality from sandboxed applications:
- Deploy the guidance library assemblies—Microsoft.Practices.ServiceLocation.dll, Microsoft.Practices.SharePoint.Common.dll, and Microsoft.Practices.SharePoint.Common.XmlSerializers.dll—within your sandboxed application. In this case, the functionality of the assemblies will be restricted by the security settings of the sandbox environment.
- Deploy the guidance library assemblies to the global assembly cache. In this case, the functionality of the assemblies will be restricted by the security settings of the sandbox environment. However, the assemblies will be available to any sandboxed solutions across the server farm.
- Deploy the guidance library assemblies to the global assembly cache, and install the full-trust proxies for configuration management and logging. In this case, the extended functionality exposed by the full-trust proxy is made available to your sandboxed solution, bypassing the security restrictions of the sandbox environment.
If you are deploying a sandboxed solution to a hosted or strictly controlled environment, you may find that the first option is your only option, because you can't add assemblies to the global assembly cache if you don't have permission to deploy farm solutions. The sandbox environment imposes limitations on each of the guidance library components as follows:
- SharePoint Service Locator. The service locator will function in the sandbox, but you can only register type mappings at the site collection level from a sandboxed application. The service locator can read type mappings from the farm level if the application settings manager full-trust proxy is installed. For more information about storing type mappings at the site collection level, see The SharePoint Service Locator.
- Application Settings Manager. The application settings manager relies on XML serialization, which creates temporary assemblies by default. This requires write access to the file system, which is not permitted in the sandbox environment. To store complex types, you must pre-generate the serialization assembly for the application settings manager and deploy it with your solution. Simple types such as strings, integers, and enumerations are generally not serialized—they are simply converted to and from strings. When you configure the application settings manager to pre-generate a serialization assembly, the assembly is named Microsoft.Practices.SharePoint.Common.XmlSerializers.dll. You can only read and write settings at the site (SPWeb) and site collection (SPSite) levels from a sandboxed application. You can read settings from Web application and farm-level settings if the full-trust proxies are installed. For more information, see The Application Setting Manager.
- SharePoint Logger. Logging to event logs or trace files requires fully trusted code. Because of this, you can only use the SharePoint Logger from sandboxed applications if the logging full-trust proxy is installed. If the full-trust proxy is not installed and you attempt to log from the sandbox, the SharePoint Logger will simply discard the logged information. The SharePointLogger class includes two virtual methods, WriteToOperationsLogSandbox and WriteSandboxTrace, which you can override to provide functionality to write to another location such as a SharePoint list if you are unable to install the full-trust proxy for logging.
The following table summarizes these constraints.
Deployment configuration |
Application Settings Manager |
SharePoint Service Locator |
SharePoint Logger |
---|---|---|---|
Assemblies deployed with the sandbox solution |
Must pre-generate serialization assemblies. Cannot read application settings at the Web application and farm levels. |
Can only read and write site collection–level type mappings. |
Must provide a custom implementation of SharePointLogger and override the type mapping for ILogger. |
Assemblies deployed to the global assembly cache |
Must pre-generate serialization assemblies. Cannot read application settings at the Web application and farm levels. |
Can only read and write site collection–level type mappings |
Must provide a custom implementation of SharePointLogger and override the type mapping for ILogger. |
Assemblies deployed to the global assembly cache and full-trust proxies installed |
Must pre-generate serialization assemblies. Can read, but not write, application settings at the Web application and farm levels. |
Can read and write site collection-level type mappings. Can read, but not write, farm level type mappings. |
Can write to the trace and event log. |
To deploy the assemblies with your sandbox application, you will need to add them to the solution package for your application in Visual Studio 2010. You only need to deploy the assemblies with your solution if you cannot put the library assemblies into the global assembly cache. For more information, see The Application Setting Manager.
Next Steps
This topic introduced some of the challenges that you will face when you develop production-quality solutions for SharePoint 2010. The rest of the topics in this section take a closer look at the SharePoint Guidance components that you can use in your own solutions to help address these challenges.