3

I'm working on a class library project which provides client applications with a lot of useful extension methods. This project is expected to be used on a large variety of platforms (versions of the .NET framework).

In order to do that I'm going to use several separate Visual Studio projects, each one for its own platform. These projects could have their own outer dependencies though the source code will be shared between them with the use of the "add as a reference" feature. That approach will allow me to change the implementation for all projects by writing code in just one file without any need to copy it to other projects. Keeping in mind differences in target frameworks, I will need to use #if compiler directive(s). The result of each project will be published as a NuGet package for a specific version of the .NET framework.

Here are two questions I have:

  1. Every new file has to be added to every project otherwise it won't be compiled and every class defined in it won't be accessible on certain platform. As you can realize it's very easy to forget that. Is there any way to avoid this kind of file tracking? Is it possible to automate it?
  2. How can I improve the whole infrastructure? What approaches and/or solutions do you use in your projects?
Igor Soloydenko
  • 11,067
  • 11
  • 47
  • 90

2 Answers2

5

In order to do that I'm going to use several separate Visual Studio projects, each one for its own platform.

You don't need to do that. You can have multiple configurations for the same project. You'll need to handle it by editing the project file, but you only need to do that once (or at least, once for each time you need to add a new platform). Use conditional compilation symbols defined in each project configuration to allow you to exclude certain bits of source code in each build configuration.

I've done this before a couple of times, and it's the approach I'm using to allow a PCL build in Noda Time. I've ended up with 6 configurations:

  • Debug
  • Debug PCL
  • Release
  • Release PCL
  • Signed Release
  • Signed Release PCL

Obviously your needs may well be different (particularly regarding signing) but it's working fine for us right now - and I think it's much better than manually keeping several project files in sync.

Another option would be to have a "skeleton" project file for each platform, and a single "master" project file, and generate the real project files for all but the master. So you'd add a new source file reference into the master project file and then regenerate all the others. This does mean writing the code to do that, mind you... or use the project we use for protobuf-csharp-port: csprojectprojector

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • :P. +1 for different configs. – Simon Whitehead Jan 06 '13 at 21:46
  • Thanks for sharing your practices. Will your approach still be applicable if some of my projects have their own outer dependencies? For example `MyLibForFW4` uses `CoolOuterLibForFW4` whereas `MyLibForWinPhone` uses `CoolOuterLibForWinPhone`? – Igor Soloydenko Jan 06 '13 at 21:48
  • 1
    @Jon Skeet: Does this apply also if you need to selectively link dll depending on the config? I asked a similar question : http://stackoverflow.com/questions/13836501/preprocessor-directives-across-different-files-in-c-sharp . As far as I understood I can't enable/disable dll linking using project config alone. am I right? – Heisenbug Jan 06 '13 at 21:52
  • @Heisenbug: I was unable to find an answer on this question. Now I'm thinking about creation of a Visual Studio extension which will automatically fill the project with source code files from specified directory(ies) every time you build the project. Using this VS Extensions I will be able to create a separate project per target platform, then link required DLLs corresponding to the platform. The only problem here is that the extension has no idea about compilation option for each file. It can't determine whether the file is a source or embedded resource etc. – Igor Soloydenko Jan 06 '13 at 23:54
  • 1
    @keykeeper: Yes, you can make references depend on properties within msbuild files too. – Jon Skeet Jan 07 '13 at 06:47
  • 1
    @Heisenbug: That question seems to be about `using` directives, not DLLs. But yes, you can make assembly references conditional (by hand). – Jon Skeet Jan 07 '13 at 06:48
  • The main problem I see with this solution is that Visual Studio doesn't really show you what's going on. It doesn't show you what files it is building or which references are being linked. It just looks as though everything in included when in fact only a subset is being built. Is there a VS extension that helps with this? – Mark Jun 04 '13 at 20:09
1

Another approach would be to use wildcards instead of including individual files in your projects. This also requires manual editing of your project files, but it would be a one-time task. I've never used this approach, but I've seen it mentioned by others.

http://msdn.microsoft.com/en-us/library/ms171454(v=vs.100).aspx

Owen Wengerd
  • 1,628
  • 1
  • 11
  • 11