Visual Studio Projects and Sitecore

|

This is a topic that I've been meaning to cover for some time now, but it is this post by John West that pushed me to do it sooner rather than later.

There are basically two ways of working with Sitecore.

  1. Your solution, and code, is fully immersed in the Sitecore web site.
  2. Your solution, and code, is outside of Sitecore's web site and you use some post build process to deploy.

John's post, and Sitecore documents, suggests that you go with option 1. I, however, do not agree that this is the right way to go. I feel that my code should not be mixed in with over 6,000 of Sitecore's files. Here are some reasons:

  1. The most important advantage is a clear understanding of the ownership of files in the solution. Everything checked into source control is explicitly owned by the solution being developed. All other files are owned by Sitecore or a third party package installed in Sitecore.
  2. I want to be able to distinguish my files from Sitecore's just by looking on the file system.
  3. If I need to ship the code to my client I simply want to zip up my 'workspace' and not have to wade through out-of-the box Sitecore files.
  4. I want my development environment to be as close as possible to a production environment. This means no .cs files in my web root

I've been working outside of the web root for three years now and wouldn't consider it being any other way. In fact, I am always wondering why you would want to work out of the web root as Sitecore suggests. I spoke to a client recently, while proving support for Team Development for Sitecore, and their answer was simply, "we didn't know better." That isn't acceptable.

Here is the way I work and highly suggest you work as well.

  1. Use IIS and configure Sitecore somewhere other than C:[Workspace][Client]\trunk. For example, C:\Sitecore[Client]\Website
  2. Create your Visual Studio solution (and projects) outside of the web root. i.e. C:[Workspace][Client]\trunk\ClientWebsite.sln
  3. Add references to any Sitecore assemblies as needed. Make sure to set "Copy Local" to false as John West suggests.
  4. Use a post build step to copy the output of your compiled Web Application project to the location specified in step 1. Or, better yet, use Team Development for Sitecore to handle the deployment for you.
  5. To debug, you will need to make a change to the Web Application project. On the 'Web' tab of the properties for your Web Application project you should choose the "Use Custom Web Server" option and enter in your development Sitecore URL. Once this setting has been specified you can now press F5 to build your project and debug normally. This may require some IIS components to be enabled, depending on your system. This will also work for IIS running on a remote machine (and virtual machines) as long as remote debugging components are installed on the remote machine.

Taking this one step further, you NEED to be using source control and automated builds in your development. Continuous Integration is also a good practice and possible using Team Development for Sitecore! Cost shouldn't be an excuse either as there are free tools out there to help you with this!
We, at Hedgehog Development, have done a good number of Sitecore sites this way and we do consider this a best practice. We are able to bring new developers onto a project in minutes and can roll out builds effortlessly.

I would love to get some feedback on this. Please let me know if you love working out of the web root as Sitecore suggests.

Update 2/2013: John West has seen the light and now agrees that this approach is sound. http://www.sitecore.net/en/Community/Technical-Blogs/John-West-Sitecore-Blog/Posts/2010/09/Create-a-Visual-Studio-2010-Project-for-a-Sitecore-Solution.aspx#communitycontent_2_CommentsList_CommentItem_14

Comments

Sean, I couldn't agree with you more. I've been a long-time fan of working outside of the web root as well and using post-build scripts (MSBuild is crazy extensible) to copy files from the solution to the web root. This approach [i]always[/i] results in cleaner solutions, easier code management, more efficient deployments and also smoother upgrades. --adam

This approach definitely has advantages. I think it is more work for someone like me who has to create lots of Visual Studio projects for Sitecore solutions frequently and quickly, and then not integrate with source code management or maintain those solutions for any length of time. I think I've heard of another approach that uses dynamic compilation to reduce the frequency of ASP.NET restarts. I think that would require code within the document root. If such a model exists, I expect it would compile the code into an assembly for deployment (not require deployment of source code).

@John, I would say that if I did what you did then I would probably do something like you have outlined; essentially a way to test out various things quickly. However, my issue is that the majority of people reading your blog aren't doing what you do. I would think the majority are working on their own "in-house" site, or, as in my case, many sites for many clients. Therefore, being that the majority probably aren't doing what you do, then they probably shouldn't work the way you do either. As for the dynamic compilation... it sounds like using the 'web site model' with Sitecore. Then maybe using web deploy projects you can compile that for production release. Interesting idea.

Just noting that I read somewhere that Windows Azure requires the Web Application Project, though there are probably ways around that. I thought it was funny because Microsoft had removed that project model in the first release of Visual Studio 2005, but had to add it back with a service pack, included it in 2008, and appeared to make it mandatory for Azure in 2010.

Post-build steps are not as good, you have to recompile the project to update the actual files. I'd suggest to create all custom files(and projects) within folder under /Website instead.

I think Alex is right. I am also sure it would be much easier and understandable to make some step for deploying/build script. That step can remove all the *.cs files from under webroot of preparing build.

Alex/Ivan, I can see some benefit to the approach you want to take, but I must ask if you work on a single site for your company or many sites for different clients, (or something else)? In my experience I have many projects (clients) that have various components to their site. For instance, I have two projects that both rely on Coveo for search. I do not want to have Coveo running on my machine so I create a virtual machine that runs Sitecore and Coveo. When I build my project, from my workstation, the compiled code gets pushed to my VM and I debug. To make it more confusing, the Coveo version are different, therefore I have each client in their own virtual machine. If I took your approach I would need to have Visual Studio running in a VM and I would need to work in that VM via remote desktop. Ultimately it comes down to preference. Using virtual machines and Team Development for Sitecore I am able to code outside of the web root, leverage source control, have a development environment closely mirror my production environment, and do continuous integration. To me, that is the best way to work.

I like the idea of working outside the webroot and we're doing this for umbraco projects aswell. But how do you handle changes done in Sitecore. Typically our developers would add new sublayouts through sitecore, to ensure database changes are done correctly. How do you handle that in a "out of webroot" project?

Nick Wesselman says:

Sean, How do you handle Sitecore module installs? It seems like after installing, you'd need them added to the base Sitecore "image" that all developers use, and that is used for deploying new environments. But then how do you isolate the "image" from the code deployed on top of it? Thanks, Nick

Alistair Deneys says:

Vote 1 for outside webroot. I also find myself creating lots of small projects to try out ideas like John does (for my blog), and I find it much easier to have separate projects outside my webroot and use MSBuild to copy the files over to a Sitecore instance on my local machine I share between all these small projects. Spinning up a whole new instance of Sitecore, complete with it's own set of DBs just to try out a little idea feels much too heavy. I understand people's frustrations of having their website restart each time you update, even for something like a CSS file (cause that should be stored in your project too; separation of ownership). I guess I've just learnt to live with it and value to separation over the convenience. Just to cover off Rasmus' and Nick's questions (for how I do it anyway), presentation components still need to be created in Sitecore, then XSLTs copied to the project and ASCX / ASPX created manually (for proper code behind) in the solution. Just make sure the path of the ASCX / ASPX is the same as the component you created. You might also want to have a look into the VS2010 plugin Sitecore Rocks! which let's you create these components inside VS. As for the modules, I install those then move the package files off to a separate folder and use MSBuild to copy those files across as a post-build step.