Post on 10-May-2015
BEST PRACTICE FOR DEVELOPING SHAREPOINT SOLUTIONS
Shakir Majeed Khanwww.shakirmajeed.com@meetsmkme@shakirmajeed.com
MySelf5 year of SharePoint
Blogger, Speaker, Hobbyist photographer
Technical Lead @ Kalsoft
Karachi, Pakistan
#Best Practice Quotes“We cannot control the winds, but we can adjust the sails.” Anonymous
“It's not necessarily the amount of time you spend at practice that counts; it's what you put into the practice.” Eric Lindros
“My secret is practice” David Beckham
Best Practice for Developing SharePoint Solutions
Content to Cover
SharePoint Solution
Farm Solutions
Working With Large List
General Consideration
Sand boxed Solution
Event Receivers Timer Jobs
SharePoint Solutions
General ConsiderationAvoid unnecessary construction
of ObjectsDisposing objectsObject CachingOptimizing code performance
Avoid unnecessary construction of SPWeb/SPSite ObjectsSPWeb
SPSite
SPWebApplication webApplication = SPWebApplication.Lookup(new Uri(System.String);
SPFarm farm = webApplication.Farm;
SPContentDatabase content = webApplication.ContentDatabases[SSystem.Int32];
Disposing objects
Disposing objects (Cont..) Symptoms
Application pool recycle frequently, especially under heavy loads
System perform poorly, especially under heavy loads
System crash or do users experience unexpected errors such as timeouts or page-not-available errors, especially under heavy loads
Disposing objects (Cont..) Why Dispose?
SPSite class and SPWeb class objects, are created as managed objects
Each instance of SPSite and SPWeb contains a reference to an SPRequest object that, in turn, contains a reference to an unmanaged COM object
Disposing objects (Cont..) Rule of thumb
Never dispose SPContext, SPContext.Site, SPContext.Current.Site, SPContext.Web, and SPContext.Current.Web.
Disposing objects (Cont..)
using (SPWeb web = new SPSite(SPContext.Current.Web.Url).OpenWeb()) { //
}
using (SPSite siteCollection = new SPSite(SPContext.Current.Web.Url)) { using (SPWeb web = siteCollection.OpenWeb()) {
//
}}
Disposing objects (Cont..)
SPSite siteCollection = siteCollections.Add(URL, "DOMAIN\\User", EMAIL);
using (SPSite siteCollection = siteCollections.Add(URL, "DOMAIN\\User", EMAIL)
{
}
Disposing objects (Cont..)
SPWeb web = siteCollection.AllWebs.Add(URL);
using (SPWeb web = siteCollection.AllWebs.Add(URL)
{
}
Disposing objects (Cont..)Download the SPDispose Check tool
http://code.msdn.microsoft.com/SPDisposeCheck
Object Cachingpublic void CacheData() { SPListItemCollection
oListItems; oListItems = (SPListItemCollection)Cache["ListItemCacheName"]; if(oListItems == null) { oListItems = DoQueryToReturnItems(); Cache.Add("ListItemCacheName", oListItems, ..); } }
Object Cachingpublic void CacheData() {
DataTable oDataTable; SPListItemCollection oListItems;
lock(_lock) {
oDataTable = (DataTable)Cache["ListItemCacheName"]; if(oDataTable == null) {
oListItems = DoQueryToReturnItems();
oDataTable = oListItems.GetDataTable(); Cache.Add("ListItemCacheName", oDataTable, ..); } } }
Optimizing code performance
SPWeb myWeb = SPContext.Current.Web; myWeb.Lists["Tasks"].Title = "List_Title"; myWeb.Lists["Tasks"].Description = "List_Description"; myWeb.Lists["Tasks"].Update();
SPWeb myWeb = SPContext.Current.Web; SPList myList = myWeb.Lists["Tasks"]; myList.Title="List_Title"; myList.Description="List_Description"; myList.Update();
Farm Solutions
Target farm level solutions to the specific web application instead of deploying to all web applications.
Try to deploy all the resource files (CSS, JPG) from within the Solution (Applicable to Sandboxed solution as well)
Sandboxed Solutions
Plan which servers will run the sandboxed solutions service.
Plan which site collections will be able to run sandboxed solutions.
Design your Sand Boxed solution as per the Site collection quota
Working With Large Lists
Working With Large ListsSPWeb.Lists[strDisplayName]
SPWeb.Lists[GUID]SPWeb.GetList(strURL)
Working With Large Lists (Cont..)
SPList.ItemsSPList.Items.AddSPList.Items.GetItemById
SPList.GetItems(SPQuery query)SPList.AddItemSPList.GetItemById(int id, string
field1, params string[] fields)
Working With Large Lists (Cont..)
SPList.Items.CountSPList.Items[System.Guid]SPList.Items[System.Int32] SPList.Items.GetItemById(Syste
m.Int32)
SPList.ItemCountSPList.GetItemByUniqueId(Syste
m.Guid) SPList.GetItemById(System.Int32)
Working With Large Lists (Cont..)
SPFolder.Files.CountSPFolder.Files[System.String]
SPFolder.ItemCountSPFolder.ParentWeb.GetFile(SPU
rlUtility.CombineUrl(SPFolder.Url, System.String)
Working With Large Lists (Cont..) Deleting Versions
SPListItemVersion.GetVersionFromID(System.Int32). Delete();
SPFileVersionCollection. DeleteByID(System.Int32);
Event Receivers
Event Receivers
Always use 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.
Event Receivers (Cont..)Instantiate an SPWeb, SPSite,
SPList, or SPListItemUpdate method
properties.OpenWeb()properties.ListItem
Timer Jobs
Always run the timer job in off hours Always perform take out the timer job
when deactivating the respective feature
Don’t use SPContext,SPContext.Current,SPContext.Current.Web
General Considerations
Use proper feature name and description.
Use the feature as it require by design. Make sure solutions have proper
consistent naming convention. Use the correct older version of WSPs
to retract the solution before deploying or upgrading the custom code
Thank You
Shakir Majeed Khanwww.shakirmajeed.com@meetsmkme@shakirmajeed.com