Often when working on Sharepoint projects there are several projects of Sharepoint 2010 VS project template in single solution. E.g. if you develop Internet and Extranet you may have 3 wsp packages (and 3 projects in VS):
- Common – contains common functionality for Internet and Extranet
- Internet – contains only Internet-specific functionality
- Extranet – contains only Extranet-specific functionality
Doing like that if customer have different environments for Internet and Extranet, it will be possible to deploy Common and Internet packages on Internet environment, and Common and Extranet – on Extranet environment.
Visual studio allows you to include Sharepoint project items from different Sharepoint projects. E.g. if you have MOPages module in Common project, you can add this module into the feature from Internet or Extranet projects. It will work, however there is one side effect: in this case assembly which is build from Common project (Common.dll) will be included to the Internet.wsp and Extranet.wsp packages as well. In our example it most probably won’t cause problems, because we anyway need deploy Common package at the same time when Internet or Extranet packages will be deployed. In this case Common.dll will be installed to GAC first time from Common.wsp, and then from Internet.wsp or Extranet.wsp (depends in what order you deploy packages).
But if it may cause problems if you have some base library package in your company (e.g. Sharepoint.Base.wsp) which you use in many projects and control releases of this package (because you don’t want that changes made in newest version will break something on the existing environments of different customers). If you will include project items (PI) from Sharepoint.Base.csproj into your project (you may do it if will include Sharepoint.Base.csproj into your solution), then Internet.wsp (or Extranet.wsp) will also contain Sharepoint.Base.dll, regardless of the fact do you use C# code from it or not. I.e. as I mentioned above you may add module project item from Sharepoint.Base.csproj which doesn’t technically require adding reference to Sharepoint.Base in VS (solution will be compiled without it anyway), but Sharepoint.Base.dll will be anyway added to your wsp.
What will happen when you will deploy Internet.wsp (which contains now Internet.dll, Common.dll and Sharepoint.Base.dll)? All 3 dlls will be updated in GAC, including Sharepoint.Base.dll. It breaks policy with controlled releases – because now it will be hard to control what version of the Sharepoint.Base.dll is installed on production (because it will be updated when you deploy Internet.wsp and when you deploy Sharepoint.Base.wsp). If you will deploy latest version of the Sharepoint.Base.wsp to the production while other sites depend on old version, they may stop working. It may cause to version inconsistency and will lead to maintenance hell.
In order to avoid this problem do not make cross-projects references of project items when use Sharepoint 2010 VS project templates. Add functionality from base project by including on feature level (e.g. by adding features from base package into your onet.xml files) or use it as is. If these features contain a lot of another functionality which you don’t need in your projects, it is better to just copy necessary artifacts from it. In this case some functionality will be duplicated, but maintenance will be still controlled.
Recently Koen Vosters from MS wrote about similar problem in his blog: Unexpected DLL in a WSP package. (Hi Koen, and thanks one more time for the great help which you made for us in Finland! :) ). I hope that my post will be more popular in search engines :)) Just kidding ;)