While most companies make sincere attempts to stay as “out of the box” as possible, there comes a point at which custom or 3rd party code becomes necessary to meet the needs of the organization. This is NOT a bad thing… SharePoint is designed to be extended. However, there are certain steps that will help ensure deployed code is as well developed as possible.
On Open Source code (Codeplex.com for example): Remember that “Open source” code should be treated essentially the same as “Custom” code. That is, if you want to take advantage of the functionality someone else provided, you should also be willing to take ownership of the enhancements, bug fixes, compilation, and packaging. There is no company or support organization to help you or provide you with fixes if there is a problem, and there is no guarantee that the source code will be available at <insert custom code download site here> forever. (Welcome to the hidden cost of open source… you get what you pay for.)
Generally, the SharePoint development team is separate from the Administration team that supports the system and it’s users, and thus they have different objectives. Developers are trying to make new stuff, while the MOSS administrators are focused on keeping the existing stuff running as well as possible… or to put it another way, developers exist to create change, while administrators are focused on reducing change to increase stability and availability. To be clear, it is a GOOD THING that these two groups have opposing goals… think of it as checks-and-balances for your server environment… but we still need to get something done, so we need a process and clear agreement on what we’re doing and how.
Below are the minimum criteria I would recommend. Note that additional process steps or criteria can be added as appropriate.
- All code (custom, 3rd party, purchased, whatever) MUST be provided/deployed as a SharePoint Solution Package.
SharePoint has a software deployment model that puts the majority (if not all) of the responsibility of ensuring SharePoint code (features, templates, etc) is deployed properly into the hands of the SharePoint Developer. This is technically correct… the developer should know the location that files need to be copied, the GUIDs for web parts to be added to the Save Controls list, the naming of specific features, any dependencies in features, any feature activation dependencies, services that should be activated, etc., so SharePoint provides with developer with a way to define this via Solution Packages.
3rd party vendors may provide code as installation packages (“setup.exe”) instead of pure solution packages. This may be acceptable as long as a solution package is ultimately the deployment methodology being used.
- All code should return with no issues when analyzed using the SPDisposeCheck tool.
Because the SharePoint object model relies on several COM components, the rules of “pure” .NET development do not necessarily apply. Specifically, the practice of relying on the .NET CLR to automatically clean up memory does not behave as is typically expected. This means that developers must ensure they specifically dispose of their objects properly in order to prevent significant memory leaks (that will only expose themselves during load testing) from occurring and creating significant problems in your production environment. SPDisposeCheck can detect the most common scenarios that these issues can occur, so provides a simple way to check for the most common errors. However, false-positives are possible, and this tool does not catch every possible code structure, so load testing should still be done… but this is a great way to identify possible issues quickly.
Tip: You can analyze the code within a solution package by changing the package to have a .CAB extension and extracting the files. You can then run SPDisposeCheck on the extracted files. 3rd party code can usually be checked in this way also.
- No Microsoft-provided or out-of-the-box files should be modified as part of the deployment (with exception).
Overwriting or directly manipulating most SharePoint files is generally considered a severely bad practice. Doing so introduces a significant risk that updates to SharePoint will cause such changes to be lost, and/or cause incompatibility as “old” files from custom solution packages overwrite newer files that contain fixes or compatibility elements with updated DLLs or code. There are exceptions (ex., docicon.xml must be updated to include the common PDF icon association), but generally updated Microsoft provided files should not be necessary.
- There should be no direct queries of any SharePoint Databases (Config, Content, or any other database created/owned by the SharePoint Farm).
Direct reading and/or writing to SharePoint databases is explicitly not supported, pretty much ever. Previous guidance on how it may be acceptable to perform read-only queries has been deprecated... even read access is now unsupported. All access to SharePoint configuration and/or content should be obtained exclusively through the SharePoint object model. (Yes, we publish the schema if you know where to look... but this is little more than interesting reading and should be essentially worthless.)
- All code should be created in a company specific namespace.
Occasionally, developers believe that in order to properly use the SharePoint object model, their custom code must be in the “Microsoft.SharePoint…” namespace. This is incorrect, and doing so will make troubleshooting significantly more difficult. Instead, the namespace (and related filenames) should reflect the name of the company doing the development. For example, “Contoso Company” might create all of their SharePoint development in the “Contoso.SharePoint…” namespace.
- All post-deployment configuration must be done through a provided UI interface.
In many cases there are two steps required: Deployment and Configuration. With deployment having been automated using Solution Packages, it would be ridiculous for us to now have several steps that require going into the configuration files we previously avoided and update numerous settings. Rather, it should be considered a requirement that, if environment-specific configuration is required, an interface for defining that configuration should also be provided. Further, the configuration for that item should be in the appropriate area for where the feature is scoped. For example, if a feature is farm-wide, the configuration should be accessible through Central Administration, whereas if the feature is scoped at the individual web site, access to the configuration pages should be visible in the Site Settings page. Interfaces for programmatically creating these links are available in the SharePoint object model.
- There should be no hard-coded strings embedded in the custom code.
Specifically, there should be no direct paths to URLs, file system paths, or anything else that could potentially change in the future. There are rare exceptions, but in 99.9% of all cases, if something can change (including the words on the screen), it will.
- Code must be reviewed and have sign-off from at least one additional developer prior to test submission.
Code reviews significantly enhance the development process and team by A) reducing common errors in code that would otherwise be found in testing or development, B) increase knowledge sharing because the reviewing developer may learn new ways to interact with various components or new software development/design patterns, C) decreasing supportability risk if a single developer leaves or is on vacation because multiple developers are familiar and accountable for the code. This will also generally increase the overall quality of the code being generated (because no developer wants to be embarrassed by their code).
- The cost of maintaining a customization must be calcluated, either in money or people-time.
Customizations are rarely "deploy and done". There are impacts to maintenance of the environment, break/fix requests, enhancements, change requests, testing, performance impacts, and upgrade requirements. The people-hours required to maintain a given customization needs to be calculated... either in a cost through a monthly charge-back model (that loosely translates to additional funding for maintenance/operations staff), or a % of a person which, over time, add up to a clear requirement for additional headcount. Without this, the scope of work required to maintain the existing environment, plus the customizations, increases over time, while the amount of time available to maintain it does not. Including the operational impact of customizations resolves this problem.
- All code must be wrapped in at least one SPMonitoredScope object.
SPMonitoredScope is a new class introduced in SharePoint 2010 that allows a developer to easily write to both the SharePoint ULS logs and the new SharePoint Developer Dashboard, providing a relatively easy means of identifying specific web parts or other activities in the rendering pipeline that may be causing a page to load slowly. At minimum, a single SPMonitoredScope should be used to identify any code within the web part itself, though more can be used (within reason) to identify specific areas that the developer may believe could more specifically impact performance.
While these items may hover back and forth between “policy” and “process”, each item contributes significantly to the ability to catch errors early and/or identify errors easily and quickly.
If you think something is missing, comment below and I may update this post with the suggestions that provide the most value.
Updated 4/5/2011 - Addedd #4 to include prohibition of direct queries/writes to SharePoint DBs and #7 no hardcoded strings.
Updated 4/7/2010 - Added #9 to include the operational costs of customizations.
Updated 5/4/2011 - Added #10 to include SPMonitoredScope for Developer Dashboard.