This is the third and last part of Sharepoint Development using Visual Studio series. For previous part:
http://www.sharepointblogs.com/tommysegoro/archive/2008/09/04/sharepoint-team-development-with-visual-studio-part-2.aspx
Note: Just change the part-x bit to go to the other series of this posting.
INTRODUCTION
I've shared to you about the different Sharepoint project types, the development methodology approach and the tools. In this particular posting I will share to you on how to plan your Sharepoint development. I've talked a bit about this in my previous posting about how you should plan your content types and fields first. Sure, requirements change but at least you reduce your "headache" if you can get as much content types and fields done as possible. In this particular posting I will share to you on how I normally approach the site creation, the implementation of features, etc.
THE TOOLS
Once again I will repeat this over and over again: You HAVE TO utilise solution and features deployment for team development. Please find on my previous post regarding the tools I've used. Anyway, I will use my own solution template for creating solutions and features on my examples/projects. Please download from http://www.codeplex.com/vs2008sp.
SITE CREATION
Personally I will go down the custom site definition path. I will not modify OOTB site definition (eg. modifying STS's ONET.XML directly) because when you start modifying OOTB files, they may get overridden by service packs or patches that Microsoft releases. With custom site definition, too you can select what features to be activated upon creating a new site, what files to appear, etc which makes sense for me.
My fellow Sharepoint developer mentioned to me before that he prefers to use PowerShell to activate the features because he can see whether feature activation succeeds or not rather than you create your site first then getting an error message. If any of you uses PowerShell to create your site/activate your features, can you please share your experience? Anyway, I personally will go down the custom site definition path because it's easier for me to categorise which site will use what features, which site use what pages, what lists to instanstiate, etc. See example below of my custom ONET.XML:
<Configuration ID="1" Name="Blank">
<Lists>
<List FeatureId="00BFEA71-2062-426C-90BF-714C59600103" Type="103" Title="Page Order" Url="Lists/Page Order" />
</Lists>
<
Modules>
<Module Name="DefaultBlank" />
</Modules><SiteFeatures>
<!-- BasicWebParts Feature -->
<Feature ID="00BFEA71-1C5E-4A24-B310-BA51C3EB7A57" />
<!-- Three-state Workflow Feature -->
<Feature ID="FDE5D850-671E-4143-950A-87B473922DC7" />
</SiteFeatures>
<
WebFeatures><!-- CUSTOM FEATURE -->
<!-- SITE ACTIONS -->
<Feature ID="69CCBDEB-6B71-4fb6-9A2E-93EBB8D792D8" />
<!--
PUBLISHING LISTS CREATION -->
<Feature ID="67A06416-3D36-44c9-8980-F10FA0181B27" /><!-- SET PUBLISHING LIST WITHOUT APPROVAL -->
<Feature ID="6873B8E8-848D-461d-9494-9422E354AE6B" />
<!-- MASTER PAGES -->
<Feature ID="5522E091-66EA-40e8-9C62-D08861A96225" />
<!-- MODIFY NAVIGATION -->
<Feature ID="2F74B5BA-BDA9-435d-84DC-DF3CA1E741A2" />
<Feature ID="00BFEA71-4EA5-48D4-A4AD-7EA5C011ABE5" />
<!-- TeamCollab Feature -->
<Feature ID="F41CC668-37E5-4743-B4A8-74D1DB3FD8A4" />
<!-- MobilityRedirect --> <!-- CUSTOM FEATURES -->
<!-- Content Type Binding -->
<Feature ID="678C0C06-1053-455b-8767-867B6B37EA75" />
</WebFeatures>
</Configuration>
Therefore, when I need to create a particular site that will require particular features to be activated, I can easily go to
Site Actions -> Create Site and create a site that uses my custom site definition and it will then have the correct activated features.
For creating custom site definition I always start from the OOTB ones. To create WSS-related site definitions, start from STS. For Collaboration Portal starts from SPS and for MOSS Publishing starts from BLANKINTERNET.
THE PROJECT
I personally will divide the project into 3 sub-projects:
- Features
- UI
- DLL
The Features project will contain feature-related stuff (except features that deploy UI such as master pages, CSS, page layouts and javascripts). So in this project you will have features that contain feature receivers, features that deploy web parts, features that deploy content types and columns, etc.
The UI project will contain UI-related stuff such as feature that deploys master pages and page layouts, feature that deploys images, CSS and javascripts.
The DLL project contains all code-behind related stuff (feature receivers, event receivers, custom fields, user controls, web-part code, etc). Why I divide the code into a separate project? It's because when you're deploying the DLL it won't affect the other elements (eg. Features and UI). The other elements will still run as normal yet you can deploy as many changes to your code as possible.
UI ELEMENTS
I will deploy CSS and images that are related to the UI directly on file system using feature. I will not upload images that are related to UI to Sharepoint image library. The reason is, when it comes to updating them, it's very-very easy and quick to re-deploy a new set of CSS, javascripts or images to a file system rather than uploading those files to Sharepoint.
For master pages and page layouts, I will also move away from using Sharepoint Designer and I will NOT un-ghost them. Updating them will be very easy and they can be source controlled using TFS/VSS if you're not using Sharepoint Designer to update them. When you want to update them, you can just re-deploy your UI project and it will upgrade all of your master pages and page layouts in the file system.
CUSTOM PAGES FOR DISPLAYING NON-SHAREPOINT INFORMATION
Let's say you need to display information from your MS CRM but in the context of Sharepoint (and inheriting the Sharepoint permission for viewing that page, etc), I will personally go down the custom page layout (or application page path). This way you can then code your page to use Sharepoint permission. In your Sharepoint custom page you can then have user controls that will display information from MS CRM.
Example: http://myintranet/Pages/ViewCustomer.aspx or http://myintranet/_layouts/ViewAdmin.aspx.
TESTING
Various testings can also be executed on a Sharepoint application (same as usual custom applications). With unit testing however, you will need to have Sharepoint installed on your machine because stuff like retrieving list item from a list, etc will require you to connect to a Sharepoint list. When I divide my projects into those 3 categories, I can easily test the DLL project without even deploying my UI and my Features (although I will need to have the actual list to be created on my Sharepoint site if I need to retrieve items from it).
DEVELOPMENT PROCESS
The development process can be the same per general custom application development. With those 3 sub-projects I have, I can check-in check-out files/features/user controls/master pages, etc and my fellow developers can then get latest and run Install/Upgrade and he will suddenly have the latest files on his Sharepoint site. That's the beauty of solution and feature deployment. It allows you to do team development.
BUILD and UAT PROCESS
The build and UAT process can also be the same as per general custom application development. I can use TFS (or other tool) to build my 3 sub-projects, deploy the features/solutions to the Test server then I can run Install/Upgrade script. The Sharepoint site on the Test server will then have the latest features and files installed.
CONCLUSION
So this will be the end of the team development series hope that you enjoy reading them and please share your experience. The team development process may take more time than just modifying things directly through the Sharepoint GUI but it's worth it. It will make your code maintenance a lot easier, it also allows you to perform code review (making sure that everyone is on the same page in terms of writing feature, code and solutions) and updating/upgrading your files will be a lot easier.
To download sample code please go to http://www.smallbusinesshosting.com.au/SampleProject.zip.
Cheers.