If you are new to
SharePoint 2010 development, building custom solutions based on the SharePoint
2010 framework is never easy. Sometimes list of types of custom components you
can build on top of SharePoint 2010 Foundation framework is overwhelming. For
the novice or even for the experienced SharePoint developers, it would be easy
to get lost into specifics of the SharePoint 2010 development. Every kind of
custom SharePoint components like web parts, visual web parts, application
pages, site pages, master pages, page layouts, content types, list definition,
site definitions, workflows, event receivers, lists, content types, field
types, etc. brings their own special challenge.
1.
Don’t ever change the
files in the out of the box SharePoint Root (14-Hive) directory.
2.
Never build your
SharePoint development environment on the host machine. Use the Virtual
Machine
instead. Virtualized environment promotes portability, playground as
sandbox,
and allows quick and easy way to snapshot the development
environments.
3.
Leverage WSPs (solutions
and feature framework) while deploying and packaging code from development to staging to production environment.
4.
Make sure solutions have
proper consistent naming convention e.g. OrganizationName.BusinessSolution.
5.
Make sure solutions have
proper feature name and description. Feature name and description would be
visible on the site collection and site features page.
6.
Make sure custom code is
compiled and packaged in release mode.
7.
Use SPUtility,
SPUrlUtility, and HttpUtility if you can. e.g. Use SPEncode to encode the HTML
and URL encoding.
8.
Since URLs can change
between different environments, use site.serverrelativeurl instead of site.url
to build the URL in code.
9.
Don’t forget to dispose
the newly created SPWeb and SPSite objects. If you create an object using
“new”, you must dispose it. (e.g. SPSite site = new SPSite(url) or SPWeb web =
site.OpenWeb()). Although SPWeb and SPSite objects use minimal managed memory,
it allocates substantial unmanaged memory. You must free up unmanaged memory
allocated during creation of SPWeb or SPSite objects by disposing the objects.
Best practice is to instantiate objects with “using” keyword in C#. (e.g.
using (SPSite spSite = new SPSite(url))). Additionally, always run
solution against SPDisposeCheck utility to ensure disposing all the objects properly
before production deployment.
(http://code.msdn.microsoft.com/SPDisposeCheck)
10.
Don’t dispose the
SPContext.Current.Site or SPContext.Current.Web object. It will be disposed
automatically by the runtime. e.g. Do not use “using” keyword with the object
referenced through SPContext (e.g. don’t use using(SPWeb spWeb =
SPContext.Current.Web))
11.
Don’t use
SPContext.Current.Site or SPContext.Current.Web objects in the Feature Receiver
to access current instance of SPWeb or SPSite . If you ever try to
activate/deactivate features using PowerShell, SPContext would fail because
it’s available only in the browser context. Instead use
properties.Feature.Parent to access current instance of SPWeb or SPSite object.
For Site collection level feature, it would return SPSite and for web level
feature, it would return SPWeb object. (e.g. use using (SPWeb spWeb =
(properties.Feature.Parent as SPWeb)))
12.
Plan to install
SharePoint Manager 2010 from the codeplex. It is a SharePoint object model
explorer and enables you to browse every site properties on the local farm by
browsing through SharePoint Internals.(http://spm.codeplex.com/)
13.
Use SharePoint Developer
Dashboard to Investigate the Page Performance bottlenecks. It gives detailed
information on resource usage, performance, user interactions and error
trapping. Use SPMonitoredScope code block to generate the custom logged
counters on the Developer Dashboard. Please note that you can enable the
Developer Dashboard at the farm level and never enable it in production
environment.
14.
Use SPGridView instead
of standard ASP.NET Gridview to inherit the SharePoint CSS, Look and Feel, and Column
filtering mechanism. On other side, Use standard ASP.NET Gridview instead of
SPGridView to full control over the tabular design and functionality.
15.
Use the List Event
Receivers to execute the code immediately. Workflows can perform similar function
but it will run as a timer job which may delay the code execution.
16.
Use SharePoint Site
Property Bag to classify the sites and persist site level metadata. You can
either use SPWeb.Properties (Microsoft.SharePoint.Utilities.SPPropertyBag
Object) or SPWeb.AllProperties (System.Collections.Hashtable Object) or Site
Property Bag Configuration Tool –
http://pbs2010.codeplex.com/. SPWeb.Properties considered as legacy approach
since it stores key and value in lowercase. SPWeb.AllProperties keeps casing of
key and value intact. If you don’t care about the persisting case, plan to use
older method SPWeb.Properties instead of newer method SPWeb.AllProperties. Here
is the reason why –
http://www.novolocus.com/2010/12/22/stupid-spweb-properties/
17.
Don’t build State
Workflows in the SharePoint 2010 using Visual Studio 2010. State
workflows may NOT be upgradable because they are not available in the .NET 4.0
which might be foundation framework for the next version of SharePoint.
18.
Use field controls on
the WCM sites instead of web parts because you won’t have page history with web
parts.
19.
For the list data access
using server side object model, Use LINQ if you can, CAML if you must. Another
argument is – Use CAML for fastest performance and LINQ for object oriented
development.
20.
Do not instantiate
SPWeb, SPSite, SPList, or SPListItem objects within a list event receiver. It
would cause significant performance overhead due to additional round trips to
the database and fail other registered event receivers during subsequence
update calls. Instead retrieve the SPWeb or SPListItem from
SPItemEventProperties. (e.g. use SPWeb web = properties.OpenWeb() or SPListItem
item = properties.ListItem)
21.
Do not use SPList.Items
while accessing list items using server side object model and try to avoid
SPList.Items in a loop expression. SPList.Items iterates through all list items
from all subfolders and all fields in the list item. To retrieve the list
items, instead use SPList.GetItems(SPQuery query).
22.
Avoid deploying DLLs to
the GAC (this has risks because of security override), instead deploy it to the
web application IIS bin directory and use custom CAS policies.
23.
Target farm level
solutions to the specific web application instead of deploying to all web
applications unless you are deploying new feature to all the applications in
the farm. This way custom feature for the specific web application won’t
available on site collection features page or site features page on all the web
applications in the farm.
24.
Build Sandboxed
solutions over farm level solutions for site collection specific custom
solutions to balance business agility and IT stability. Understand the
limitations of the sandbox solutions. Create site collection resource quota
templates in the central administration. Another argument against sandbox
solutions is it has resource quota points estimation issues for heavily
collaborated sites.
25.
Plan to disable the
SharePoint Designer at the farm level and enable at the web application and
site collection level as needed.
26.
Instead of Custom Site
Definition, use Web Template or Feature Stapling capabilities to add custom
features on the out of the box site definition. I would also prefer Custom
Coded Site Templates from scratch by creating site based on team or blank site
template and activate features as needed. Also, word of caution – Never change
out of the box site definition.
27.
Deployment discipline –
During the deployment and retraction process while updating or upgrading custom
solutions, please use the correct older version of WSPs to retract the solution
before deploying or upgrading the custom code with newer version of WSPs. This
would ensure activating or deactivating features reference correct version of
WSPs.
28.
Although the CSOM, the
REST interface, and the SharePoint ASP.NET Web services are all available when
you develop server-side code, the use of these APIs in server-side code is only
recommended for accessing data from another farm. Using the server-side object
model is more efficient than using any of the client-side APIs.
Hope it will be helpful.