13

I've started an open source MVC4 project that is using some other open source project as a dependency. I've forked the other project and will be modifying it according to my needs. The problem I'm facing is how to keep these projects depending on each other, but maintained separately. Yet people who git pull my project, would get the dependency project as well?

  1. I can slam all the related code from other project into my repository, but this way I won't be able to contribute to a fork of dependent project. I'll just become a part of my repository. Not really want to do that.
  2. I can maintain other project completely separately and copy *.dll files into my project. And commit dependent dll files into git. This is nice, but I loose ability to develop two projects at the same time, along with stepping into dependent code on debug (well, maybe not if copy *.pdb files along)
  3. Similar to point 2, I can build nuget packages from dependent project and add them to my main project - again, can't really develop both projects at the same time, need to switch contexts.
  4. With some magic have a solution file that combines projects from my repository and from dependent repository. On every build, copy dependent dll files to /lib folder and commit them. This way I don't need to switch contexts between separate projects. But the drawback is when other contributors git pull my project, they don't get dependent project, and solution files will likely be broken for them, because it'll reference project that is not in the repo.

How do you organise your code in this case?

trailmax
  • 34,305
  • 22
  • 140
  • 234

3 Answers3

6

Usually I use nuget for all my dependencies. When I fork a project I will deploy it on nuget and also on symbol source. In this way you can step inside the dependency source without problems.

For more information on symbol source and nuget see also: Creating and Publishing a Symbol Package. To enable symbol source debug see http://www.symbolsource.org/Public/Home/VisualStudio.

You must also remember to enable Nuget package restore.

With this solution you can't modify source code but at least you can debug it.

Davide Icardi
  • 11,919
  • 8
  • 56
  • 77
  • Yeah, nuget package with symbols included, probably the best option. Symbol source is an interesting resource, have not seen it before. Thanks! – trailmax Mar 13 '13 at 11:51
1

I use something similar in concept to CMake, but entirely within Visual Studio. There's the relatively unknown feature of property files, which can be included by solutions. This allows you to create a file containing only paths to dependencies, include the libraries you can and set relative paths, and then require people to set the appropriate paths for the other dependencies you can't/don't want to include.

With a little bit of work, it comes out fairly clean, and is super easy to automate through TeamCity and other similar tools (each build agent can set the variables to indicate where it keeps dependencies).

For small dependencies and ones that have been tweaked to work with my project, I keep an archive or the loose files in the repository, and use the properties file to reference those. Others have instructions on where to find them and how to edit the paths.

If you're interested in such an approach, I can go into some more detail. It took a bit of work to figure out, as property files aren't super well documented, but is working pretty neatly.

ssube
  • 47,010
  • 7
  • 103
  • 140
  • that sounds interesting. Any links to articles where I can read about those "property files"? – trailmax Mar 15 '13 at 22:47
  • are you talking about these? http://msdn.microsoft.com/en-us/library/a4xbdz1e(v=vs.110).aspx – trailmax Mar 15 '13 at 22:49
  • Yep, those are the ones. I've set it up with two property files: one is purely dependency paths, and I supply them and all of my version information through the commandline to most of my builds (in TeamCity, that works simply by using "system" variables). The other is common project settings for each configuration (output path patterns and the like). Appropriate use of VS' variable replacement in the include/library include paths and the ability to use environment and property variables in headers (passed through the CLI) make for a pretty flexible and well-organized build. – ssube Mar 18 '13 at 15:02
  • You do have to hand-edit some property files at first and set up the includes, but it's not complicated, just sort of round-about and not super documented. For an example of how I have it set up, check the .sln and .props files [here](https://github.com/ssube/VoodooShader). Note that you have to import the property file from each project, and in the property file set both the properties (the actual variables) and if you want to use them in headers, a `` based on the variable. – ssube Mar 18 '13 at 15:03
  • That looks pretty awesome! I'll have a go on that, once I'm back to the projects. – trailmax Mar 18 '13 at 15:06
0

In case you are not creating circular dependencies, following is an idea:

  1. add a new Class Library project with a unique name, say ClassLibrary1, to the solution

  2. in the Build page of its project settings, config Output path to application output path

  3. in the Build Events page, add the following line to Post-build event command line block:

    del "$(TargetPath)"
    
  4. repeat step 1 to 3 but giving another name, say ClassLibrary2, and config Output path to the source path of ClassLibrary1

  5. set Project Dependancies of ClassLibrary1, check on ClassLibrary2

  6. add all other project as project reference to ClassLibrary2, leave Copy Local with default value true

  7. build ClassLibrary2 once, and all DLLs now are in the source path of ClassLibrary1

  8. add them to references of ClassLibrary1 and leave Copy Local with default value true

  9. set Project Dependancies of application and all other projects which are not cause circular dependencies, check on ClassLibrary1

  10. add references of other projects, from the path the DLLs were put in ClassLibrary1

  11. set Copy Local of all these added DLLs in other projects to false

Thus, the project ClassLibrary1 be a central control of the external libraries of your solution. Each time you Rebuild Solution(or just build the application), ClassLibrary1 copies the latest DLLs add to its references to the application output folder, and deletes the DLL it generated itself named ClassLibrary1.DLL. The application and dependencies at either compile time or runtime would use the same version of DLLs, you don't need to do extra deploying or check each deployments.

Ken Kin
  • 4,503
  • 3
  • 38
  • 76
  • 1
    Basically you are explaining how to implement part 2 from my question. Thank you, but technical part is not a problem here. I'm more interested in the workflow. Because this way I need to switch between solutions/contexts and I don't want to do that. – trailmax Mar 15 '13 at 22:43
  • Why you still need to switch with in this way? – Ken Kin Mar 15 '13 at 23:13
  • Because I can't have both projects in one VS solution - it will make the project broken for other people. – trailmax Mar 16 '13 at 00:00
  • @trailmax: This approach in fact can be applied repeatedly, that ensures you will not break the consistency from others. But since you think this would not solve your problem completely, I'm going to delete it. – Ken Kin Mar 16 '13 at 00:36
  • No, don't delete it. Some people might find it useful in the future. But I'm not sure I completely understand your train of thoughts. – trailmax Mar 16 '13 at 01:19