Sharing the experience search

Search sharing-the-experience.blogspot.com
Showing posts with label Feature Stapling. Show all posts
Showing posts with label Feature Stapling. Show all posts

Thursday, June 21, 2012

SharePoint: How to build SharePoint application wrong. SharePoint Karma



Whenever I refer to SharePoint development strategies, I always end up with SharePoint deployment strategies.


I am aware that in SharePoint world there are people who prefer to do customization via SPD and without a traditional development cycle.


This post for others... who wants to preserve a development cycle and who wants to have a fully automated and predictable deployment:
- via wsp files (or sandbox solution)
- and specific actions (like a feature activation) which is shipped as  PowerShell\stsadm commands. (Best Practices: Sharepoint Application Development Life Cycle)


How do you choose between content customization and code-based approach?
If you need to deploy anything on the server, that's a sign that's your approach is code-based customization.


Here is a quick SharePoint karma guide for code-driven development for SharePoint. Each wrong action will lead to a specific strong deployment reaction.
All described actions I saw done by developers. I hope this quick guide helps you to avoid pain of SharePoint deployment.


Action: Create a site locally manually. And then develop some other features.
Reaction: Deployment will be hard to other environments. You will need to re-create a site manually and hope that you haven't skip any steps.
Recommended action: create a custom site definition(onet file).It was a recommended approach since 2007. But I heard it's not what will be recommended in SharePoint 15. In SharePoint 2010 you have 2 options:
 - a web template that is shipped via sandbox solution and placed in the content db;
 - a site definition that is shipped via wsp file and deployed on the server.
Custom web templates (the preferred approach) and custom site definitions (which in some scenarios you must do)


Action: Create stp to deploy first version of the site. You know that in the future you need to change the site structure.
Reaction: Once you have created a site from a template, there is no way you can change structure via stp
Recommended action: Use site definition and feature stapling approach for further releases. In SP2010 you can make the changes for some features that is shipped via site definition using Feature Upgrade


Action: Build a wsp, place in it only eventreceivers for specific list with expectation that the list will have appropriate structure (someone should change the structure of list and then register the eventreceiver)
Reaction: As you can guess by action, you will not have stable behavior on the environment,since half of the deployment should be performed manually. I can only hope that you keep your deployment documentation up to date.
Recommended action: If you need to develop an eventreciever for the list that should have specific fields or content type, you should describe the list in the list template feature. Package the list template, list template instance and eventreciever register features as a bundle in wsp file.

Action: Every time is time for deployment - create a new site as a blank site - and create all object manually, copy files from original site to the destination and than replace hard-coded id in the file - manually
Reaction: It's messy and prone to errors.  There is no way to make such site automatic deployable
Recommended action: consider best practices of SharePoint development, use packages to deploy and feature upgrade for further releases. In case you need make some data structure changes - use SharePoint object model, write the code and package as a ReleaseFeature ( Feature stapling). This approach will allow you to keep track of all your structure changes on the existing site, plus you still can use the site definition to create a new site, and after the creation the feature stapling will do change work as it did for the existing one.


Action:Write a code to send an email\interact with end-users without environment variables
Reaction: If you miss configuration settings for your interactive logic, you miss control over it. You may end up with end-user notification sent while you are testing the application.
Recommended action: Choose approach that suits your needs best:
- property bag on the specific object (site, list, item ,etc ) (One of the way how to handle the property bag - SharePoint Property Bag Settings 2010)
- hidden list with environment variables.


Action: Manually copy to the environment all custom master pages and customized OTB SPD web parts
Reaction: It's messy and prone to errors.  There is no way to make such site automatic deployable
Recommended action: Package master pages in a feature to deliver to the server.
Regarding OTB SPD web part -there is no easy way, since the web part holds the id of the specific object from where the data is pulled. So this object will not be valid on other environment ( but in case you have developed on the copy of the prod content db, you are fine)
We have decided to develop a custom feature receiver to deploy such web parts - File provisioning: a hard-coded list id replacement


Action: Deploy report files with data source - a list asmx with hard coded List ID
Reaction: If you developed the data source (a list) that doesn't have the same id as in prod, you will have to manually change the data source after deployment.
Recommended action: To make it transportable - you can think of msi installer with parameters to swap hard coded value to a new one.


Action: Create a site groups manually and have the logic that gets these groups by IDs
Reaction: It’s prone to errors. If someone delete the group and then create a new one with the same name. You hardcoded value in the logic will break.
Recommended approach: Try the approach:
- create custom code feature which creates the groups. In the logic verifies if the custom groups exist and the permissions for them are right. If the groups don't exist, re-created them in the code.

Action: Create your own field as a counter that looks at id and has some increment value in the config file. Every time user deletes the records, you have to change the increment value in the config file.
Reaction: What???
Recommendation: I saw such application that works several years in the Prod with regular request from developer to change the increment. Last time I have checked the increment was gravitating to number 42)).
So never do such thing. This is approach is plain wrong. If you need,for some reasons, to keep ids for list items in strict order and you don't want to skip a number even though the user deletes the item and your next SharePoint id will not be subsequent to previous one, consider:
- to create a calculated field;
- to implement event receiver on the updated\created to keep the counter up to date.


And overall bad actions:


Action: Developer's objection: “It’s working on my local machine, so it is supposed to work everywhere”
Reaction: Depends on how you thought about implementation plan (if any), you may end up with the code that will work nowhere except your local machine.
Recommendation: Before you start coding for SharePoint, think through how you see your changes will be deployed.


Action: Administrator's easy fix: “If on the feature on the Prod gives you a headache - uninstall  the feature”
Reaction: Some sites will may lose the functionality that they needed from uninstalled feature.
Recommendation: Analyze what uses this feature 



Action: Project manager accusation\question: "This is sign of careless and sloppy work. How can we fix it?"  
Reaction: A team will not collaborate to fix the issue since they are considered careless and lazy
Recommendation: Respect the work of others, be aware the world is not perfect, we are here to make it work at some extend. Ask you question in the polite way to get a faster and constructive answer.



Good deeds to you and light consequences.

Monday, April 4, 2011

Custom Site Provisioning: webtemp.xml and ProvisionClass

 If you read this article - you are already so deep in SharePoint that everybody else lost hope to get you back)
  I guess you know what's onet.xml and and webtemp*.xml. For them who still doesn't know but struggles to grasp the concept: Easy to read the article "How the SharePoint is built"
  For them who know :
If you look at webtemptsps.xml (out of the box webtemplate under 12\TEMPLATE\1033\XML) you will see that a MOSS collaboration portal uses the custom provision class which is really handy when you want to create a several sites from one click:

<Template Name="SPSPORTAL" ID="47">
    <Configuration ID="0" Title="Collaboration Portal" Type="0" Hidden="FALSE" ImageUrl="/_layouts/1033/images/template_corp_intranet.png" Description="A starter site hierarchy for an intranet divisional portal. It includes a home page, a News site, a Site Directory, a Document Center, and a Search Center with Tabs. Typically, this site has nearly as many contributors as  readers and is used to host team sites."
      ProvisionAssembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"    
      ProvisionClass="Microsoft.SharePoint.Publishing.PortalProvisioningProvider"    
      ProvisionData="SiteTemplates\\WebManifest\\PortalWebManifest.xml"
      RootWebOnly="TRUE" DisplayCategory="Publishing" VisibilityFeatureDependency="97A2485F-EF4B-401f-9167-FA4FE177C6F6">
    </Configuration>
 </Template>

Long story short - You can create a class inherited from SPWebProvisioningProvider and override Provision method to write you own logic how you want to create site. You still need to use the method spweb.ApplyWebTemplate inside the provision method. The only plus of using you own Provision provider - you can add your own additional logic.

 !Be mindful
    -  spweb.ApplyWebTemplate is asynchronous (you can refer to this post you want to resolve the issues related to this fact)
   -  make sure that you don't apply the web template from which the current provision takes place (it creates an infinite loop)

The more detailed explanation how to write custom Provision provider is here - SharePoint Site Provisioning

P.S. When you need to make sure that additional logic should take place after the site creation  - use the stapling feature!

Thursday, August 5, 2010

Sharepoint: How to survive after the first deployment on Prod

I have encountered a main problem with update the existing site which was created from custom site definition. It's almost impossible to guarantee that site will survive in case something is changed in the list schema.
It's worth to notice - that described method above is not supported by Microsoft:




 Here is a helpful terminology about the site definition and site template


And finally as a "panacea" for all this deployment hell :feature stapling
The real example how I use it here

In essence, you can't deploy a new list schema (ex. remove some fields, change type for existing fields) over already deployed site. The only way to do it -through object model.

Here is the additional tips about the object model pitfalls:
Additional tips about Sharepoint API

Just found old and "unsupported" msdn article which cast the light about difficulties of sharepoint redeployment:
Adding Functionality That Affects the Existing Application

Friday, June 25, 2010

Sharepoint development: Unsupported scenario

After 1,5 years of working on Sharepoint I realized completely that way we are doing Sharepoint is NOT SUPPORTED... which is not a big surprise.
This kind (Sharepoint) of development isn't intended to live the same way as ASP.Net development:
Here is an article to MUST read before to start invent a vehicle to drive everybode crazy)

To be short, after Prod release - you can't change the structure of data or event master page through the same way as you did development (site template or list feature), you should switch to use the Sharepoint Designer or get in touch with a feature stapling 
The real hands-on "how to use the feature stapling" - Feature Stapling in Use

Tuesday, May 4, 2010

Feature stapling

If you have created a site definition, there are several ways of using features with it. These are:-
  1. Create a site from the definition and subsequently deploy your features to the site.
  2. Include the features in the site definition (onet.xml) before using it to create sites.
  3. Use feature stapling to associate your features to the site definition. 
Copy-pasted from a short and crisp article about feature stapling 

After extensive use of  the feature stapling  - I have discovered  that  the order of features in the staple feature is not GUARANTEED. Stapling features fires up when site is being created from certain site template configurations. Once the staple is fired up it runs Activating event all features that are listed under it. And because an Activating event is asynchronous all features are running pretty much at the same time, and who knows which features will be after which.

In my case I really need to know the exact order of execution.

My scenario this one: I have on prod a  site which was created from the site template. Once a while we need to deploy release for it. We stick with a procedure to make structure changes from OM(object model). So every release is a new code feature which has to be run over the existing site. To make possible to create a new site from the same site template and still have all the release changes - the feature stapling comes to play -it holds all feature releases which were created after the first release. At some point the latest release features expects the existence the changes made before it by older release.
As we know the feature stapling won't assure the exact order. My approach is to have only one feature in the stapling feature with name "ReleaseActivator":
 And here is the ReleaseActivator feature itself:

 And the custom code inside does the order magic:
P.S.
I have re-factored the concept and instead of using stsadm I use Activator.Instance(t) :





and the type I put in the feature property:
(The value attribute is not in use, but I keep it just in case).


Good luck with SharePoint! You will need it.