I have a rather large solution consisting of about 10 different projects. Until now we have shipped the entire solution as a whole to customers, but we are looking into shipping a stripped version of our software.
To this end I would like to exclude several projects from the solution. I know that you can prevent projects from being built in the solution configuration manager. Using macros all code references can be disabled when the stripped configuration is chosen. Unfortunately this does not take care of the project references. Can I make these references conditional depending on the chosen configuration?
It should be a pretty simple matter to remove the project references from the project file using a small script - it would just be a case of removing lines adding those references. The project file format is quite simple.
I suspect that's likely to be the easiest solution.
I think that this should be done when you build your projects for production. Simply enclose all code that needs to disappear between a compiler-level IF, that checks for a defined compiler directive. If on, then the code between the IF and ENDIF will not compile. This works for code files only.
For anything other that you need to take out, just make up your own way, depending on the file format, as Jon Skeet mentioned. But once you put that into build scripts, you need not care about it any more - no switching configurations, etc.
Your best bet is to create separate projects for your "stripped down" solution that references only those other projects you want. Reference the same code. Create a separate solution to hold those projects together.
They can all live together in the same folder structure, too.
For example:
MySolution/MySolution.sln
MySolution/MyStrippedDownSolution.sln
MySolution/MyProject1/MyProject1.csproj
MySolution/MyProject1/MyStrippedDownProject1.csproj
MySolution/MyProject1/MyClass1.cs
MySolution/MyProject2/MyProject2.csproj
MySolution/MyProject2/MyStrippedDownProject2.csproj
MySolution/MyProject2/MyClass2.cs
MySolution/MyProject2/MyProject3.csproj
MySolution/MyProject2/MyClass3.cs
MyProject1 and MyStrippedDownProject1 reference MyClass1
MyProject2 and MyStrippedDownProject2 reference MyClass2
MyProject3 and MyStrippedDownProject3 reference MyClass3
MySolution references MyProject1 and MyProject2 and MyProject3
MyStrippedDownSolution references MyStrippedDownProject1 and MyStrippedDownProject2
MyProject1 references MyProject2 and MyProject3
MyStrippedDownProject1 only references MyStrippedDownProject2 -- it does not reference - MyProject3
There's lots of info in http://bytes.com/topic/net/answers/444853-conditional-assembly-reference that I found very useful for resolving a similar question (it pertains more to assembly references than project references though). MSBuild get assembly reference from ProjectReference might help with bridging between.
Related
We are doing a project that uses interfaces and Unity to resolve concrete implementations of classes.
My questions is the following: I need to get my dll's all into the same folder otherwise unity will not be able to resolve the interface etc. So according to me I have a couple of options:
1. Add the projects with the implementations as references and let VS copy the files to the output folder (for some reason this just feels like a hack)
2. Change the build location of all my projects to build to the same folder
3. Create a post build event to copy all the files needed to whereever they need to go
I have implemented to second option but this could lead to files in your build folder that should not be there. I am not a big fan of post build events, so I would like to ask from other people using Unity what they found to be the best solution for them.
Thanks in advance
The first approach sounds like the right one to me. Your project does depend on the implementation libraries; it doesn't express that dependency directly in code, but it requires them, so it seems reasonable to add a reference to them.
This is basically the same situation as where you've got three projects, where project A depends on project B, which depends on project C - you need to explicitly add project C as a reference within project A. Visual Studio doesn't work out transitive dependencies for you (at least it didn't the last time I checked).
I have a class library project, lets call it CoreLib.
CoreLib has two references to 3rd party DLL files 1.dll and 2.dll
Because I love reusability so much, I want to be able to use CoreLib in as many places as possible/needed.
So if I had a project called BigProjectA and another project called BigProjectB and they needed to leverage the functionality provided by CoreLib, all I would have to do is add a reference to CoreLib in those projects (BigProjectA and BigProjectB).
That is fine, except when I go to copy over my output folder (bin directory) to another person's computer, I can't guarantee that they have 1.dll and 2.dll on their machines.
For that, I just set Copy Local to True for 1.dll and 2.dll references in the CoreLib project.
When building the CoreLib project I can see 1.dll, 2.dll, and CoreLib.dll files. That is PERFECT!
But in the projects referencing CoreLib, only CoreLib.dll is copied over, not 1.dll and 2.dll.
Am I missing something? Copy Local set to True, but only copies for the CoreLib project. So even though they are in the same solution, and I'm adding CoreLib as a project reference to the other projects, I still dont see 1.dll and 2.dll copying out to the other bin/Debug, bin/Release folders of the other projects (BigProjectA and BigProjectB).
Is there an easy solution?
The easy solution is to either:
reference 1.DLL and 2.DLL in projects which have a binary reference to CoreData.DLL
Add CoreData as a project reference to BigProjectA and BigProjectB instead of as a binary reference
In the first scenario, CoreData's dependencies are not automatically output by the compiler. If the CoreData project is added to the solution, its dependencies will be output. Hence, to use CoreData as a binary reference, you must also reference its dependencies.
There is nothing wrong. In projects BigProjectA and BigProjectB you have a references to only CoreLib, so they "care" about coping only it, cause they have no any clue about it's dependencies. What you can do to resolve these kind of issue, is to add for example PostBuildVEent in your BigProject.. to copy also CoreLib dependencies.
Or add reference to CoreLib project, if you can.
Another solution, is to consider DI like a technique to avoid strong coupling of references. So, if in BigProjectA or B you don't care about functionality provided by 3rd party libraries in CoreLib, for you should be enough to just copy CoreLib.
Good answers guys....but I actually just ended up using ILMerge. Seemed safer/less annoying.
Thank you though
I've got a legacy project in VS2008 that we're about to start refactoring for better componentization. The references between the 150 projects in the solution are messy, so as a starting point, I'm trying to at least get to a point I can have a few projects use binary references to other projects while others use project references. (For build time reasons)
To Illustrate, given projects A, B, and C, I'd like to see...
A references C.dll
B references C.csproj
Now the problem is I need to make sure that C.csproj builds before A.csproj. I know I can control build order using project dependencies, but this appears to cause exactly the behavior I'm trying to avoid... building A always causes C to build. I'm sure I can monkey with the proj or sln files directly to get things to build in the order I want, but I'm also sure that will get overwritten in short order by VS's automatic magic.
Is there some way to control this order reliably, or am I missing something obvious here?
Thanks...
Separate related components (.csproj) into individual solutions. This enforces binary references across package boundaries. It also forces you and other developers to group components by layer.
Then use your build process to build solutions in correct order starting with the least dependent packages.
In my estimation, from an SCM standpoint Solution == UML Package == Merge Module (all solutions create a merge module)
You could make custom msbuild files instead of relying on the .csproj and .sln files, such that, depending on the target chosen, it will only build certain assemblies. It would require learning msbuild if you don't know it already though.
If I have an assembly (A) which references another assembly (B).
I want to reference A in a project, I add the reference and it copies A into my BIN directory. It does not copy B as well, even though A depends on it, so the code doesn't compile.
How can I set things up so that whenever I reference A, both A and B get copied to my bin directory?
In Visual Studio, add each project to the same solution. Ensure you use Project References instead of direct file references (ie browsing for the assembly).
I dont think there is any way around what you ask other than to explicitly add both. I dont think however adding projects for the sake of getting references copied is a viable solution to the issue. Not all projects that a solution depends on should necassarily be added to the solution. This would completely depdend on your overall project structure, processes, source control, division of labour, etc
Reference both A and B.
Unfortunately you'll have to manually add both. This is what happens to me as well whenever I use pre-3.5 versions of NHibernate: it requires both log4net and Iesi.Collections assemblies. So I have no choice but to manually include a reference to both in all my solutions that implement NHibernate.
This is more of an issue, of course, if you only have the DLLs. If it's a project that you have a codebase to Visual Studio itself will warn you beforehand that the references are missing.
How about adding them to Global Assembly Cache?
At the company I work for we have a "Utility" project that is referenced by pretty much ever application we build. It's got lots of things like NullHelpers, ConfigSettingHelpers, Common ExtensionMethods etc.
The way we work is that when we want to make a new project, we get the latest version of the project from source control add it to the solution and then reference the project from any new projects that get added to the solution.
This has worked ok, however there have been a couple of instances where people have made "breaking changes" to the common project, which works for them, but doesn't work for others.
I've been thinking that rather than adding the common library as a project reference perhaps we should start developing the common library as a standalone dll and publish different versions and target a particular version for a particular project so that changes can be made without any risk to other projects using the common library.
Having said all that I'm interested to see how others reference or use their common libraries.
That's exactly what we're doing. We have a Utility project which has some non project specific useful functions. We increase the version manually (minor), build the project in Release version, sign it and put it to a shared location.
People then use the specific version of the library.
If some useful methods are implemented in some specific projects which could find their way into main Utility project, we put the to a special helper class in the project, and mark them as a possible Utility candidate (simple //TODO). At the end of the project, we review the candidates and if they stick, we move them to the main library.
Breaking changes are a no-no and we mark methods and classes as [Obsolete] if needed.
But, it doesn't really matter because we increase the version on every publish.
Hope this helps.
We use branching in source control; everyone uses the head branch until they make a release. When they branch the release, they'll branch the common utilities project as well.
Additionally, our utilities project has its own unit tests. That way, other teams can know if they would break the build for other teams.
Of course, we still have problems like you mention occasionally. But when one team checks in a change that breaks another team's build, it usually means the contract for that method/object has been broken somewhere. We look at these as opportunities to improve the design of the common utilities project... or at least to write more unit tests :/
I've had the EXACT same issue!
I used to use project references, but it all seems to go bad, when as you say, you have many projects referencing it.
I now compile to a DLL, and set the CopyLocal property for the DLL reference to false after the first build (otherwise I find it can override sub projects and just become a mess).
I guess in theory it should probably be GAC'ed, but if its a problem that is changing a lot (as mine is) this can become problematic..