- Steve McNiven
Creating innovative software is a lot of fun. Usually this is the equation for coming up with some pretty useful plugins, modules, and applications. Sometimes they are so useful that I distribute them to communities to use for their own projects. This way, I feel as if I am contributing to the evolution of technology and even humanity :)
There are some tedious tasks involved when doing this that slow down my development, which is not so fun. If you develop solutions targeted for multiple versions of a software, you will be sure to get this error back from the community:
Could not load file or assembly 'MyAssembly.Sub, Version=3.7.2096.3, Culture=neutral, PublicKeyToken=dfeaee3f6978ac79' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
A term coined over a decade ago still applies even today. The problem is that the project was compiled referencing a specific version of a software, then someone tries to load your plugin into a software under a different version.
Juggaling Multiple Versions
Even though you are providing one solution, you are forced to maintain multiple projects, each referencing a version of the software you are targeting. What if your code is identical for all software versions? This means you will have to keep the folders and files synchronized with every update you do. This is where it becomes tedious since you have to duplicate your projects for each software version and reference the respective DLL’s for that version. What a waste of space, time, and energy! So how can you easily share code and write reusable components for all versions of the software?
Welcome to Project Linker!
There is a little known tool called Project Linker that lets you create a link to another project. The reason why it is not commonly known is because it is mainly used in Silverlight and WPF development due to a complication that exists in that combination, but the concept can be used in any development.
You may already know that you can create a link to another file so you can maintain just one code file. However, the beauty of linking on a project level is that it will automatically create and maintain links from a source project to a target project for sharing code that is common between your target versions. Therefore, shared code can be written once and built for the target environment. The trick is that each project manages its own references, resources, and code specific to the target software version. What a relief!
Installing Project Linker for Visual Studio 2010
The following procedures describe how to install the Project Linker:
Go to Extension Manager in VS 2010
Search for Project Linker
Install Project Linker extension
The Project Linker is available as a Visual Studio extension
Project Linker Usage
To link a source project to a target project, right-click the target project, and then click Add Project Link. In the Select Project dialog box, click the source project, and then click OK. The Select Project dialog box is shown in below:
Project Linker Dialog
Once the projects are linked together, a file added to the source project will create a link to the original file in the target solution. Same goes for folders too.
Linked Projects: In this case, ‘SilverlightApplication1’ is the source project where you create and maintain your code. Once a file or folder is created, the same is automatically created in the ‘WpfApplication1’ project!
Tips for Project Linking
Below are some things to keep in mind when linking projects:
Use the least common denominator as your source project.
If you are linking existing projects, you can trigger the initial linking synchronization by selecting all folders contained in the source files and click on “Exclude from project” in context menu. Then after enabling “Show all files” options and include them back, the Project Linker will kick in and will link all added source files to the Target Project.
Keep the namespaces in the project properties the same for the two linked projects. This way, your code can remain identical.
Use the Conditional compilation symbols in the project properties if you want to apply specific code based on the version you are trying to target. This makes using #if COMMUNITY #Else #Endif conditional statements possible.
I hope this helps you manage your code easier when multi-targeting software. Although you may have several projects in your solution, now all you have to focus on is your code!
What Next? Facade Pattern!
You may already be fortunate enough if your software vendor provides a facade pattern design. With the facade pattern, you can develop version-agnostic code that does not depend directly against a versioned DLL. This would mean you do not need multiple projects to support different versions! It is a very elegant way to handle this problem. Check out Sitefinity 4’s API to see how they handle this for their community.