I'm writing a class library in C#/.NET.
I need to compile it for two different frameworks:
4.0 (using for debug myself)
3.5 (using on client).
I want to have one set source files for the two projects, so I can make corrections in 1 copy of files and they are included in the other project automatically.
Now, if I even use "add existing item", VS 2010 creates copies; and I need to copy the latest versions every time.
I can't just change a target in project, because I'm using different versions of .dll references, and because ms vs has some quirks.
You can use the Add as Link feature.
It goes like this:
Right-click where you need your (existing) file to be
"Add" -> "Existing Item"
Select your file then click the arrow on the "Add" button and choose "Add As link" (see screenshot below)
A link to the file will be added to the project instead of a copy
One option is to use the Add As Link options mentioned by the others already, but you have more options than that:
Portable Class Libraries are a special kind of project that allow you to specify which versions of .NET you want to target. The compiler then outputs the respective assemblies for you. The advantage of this technique is that you have one version of the source that compiles to both frameworks. The disadvantage is that you can't use features that the lowest common denominator .NET framework doesn't support.
Source control branching & merging allow you to actually maintain 2 similar but different source files. You have one version that is the master version, then after applying a change to it, you merge it to your projects that produce the actual output. The advantage of this technique is that you can have two completely separate files, so you have a lot of freedom. The disadvantage is that you have two completely separate files, which can be hard to manage.
Do better MsBuild trickery. Using the <choose>/<when> construct you can conditionally include references to a specific assembly version depending on a condition. The target framework version and other fancy settings can also be managed through MsBuild, but you can't always edit these through the UI. You can use this in combination with #if MY_CONSTANT to create conditionally compiled parts of the application
You can create a .NET Assembly that you reference from both projects. You set the .NET version to the lowest version, 3.5 in your case. Visual Studio 2010 and later have multi-targeting support and you can mix and match .NET framework versions in one solution.
What kind of qircks are you running into, if you share (part of) your project files, we might be able to resolve those for you.
When adding file to project choose "Add as link" not just add.
Related
I have an issue including a self-built library to a C#-project. I have created an own class library called ClassLibrary1 just to learn how to add libraries on Visual Studio 2019.
So I have written some simple code in a newly created .NET-class library project and have clicked on "create new solution" (directly translated from my german IDE-language. Maybe it's called slightly different) after writing the code. Back in the C#-project, I have selected the dll-file from bin/Debug/ of the class library's project folder.
After I have set the checkmark, the dll-file was shown in the solution-explorer under Assemblys like expected. But the issue I now have is that I still cannot use the ClassLibrary1.dll-file in the cs-file in this very project as I expected via the command "using ClassLibrary1;". It only shows me the error message "type- or namespacename "ClassLibrary1" not found" when trying to compile the C#-project and I don't get, why this is the case.
It seems like it has to be a very obvious problem but after some research on the internet and trying some things by myself still nothing has changed.
Thanks in advance for helpful replies.
The by far easiest way to manage a library is to use project references. Ensure that your library and the project that uses the library is in the same solution. Then right click the "references" and select "add Reference", go to the project tab and add a checkbox for the library. Read more about managing references.
You might also need to add namespaces for the classes you wish to use in the source files.
I would not recommend managing using file-references to lose dll-files, since it can easily become a hassle to manage. I.e. if you create a new version of the library you would need to build, and explicitly replace this file in all other projects and update all the references.
If you want to share libraries between multiple solutions the more popular solution would be to setup a nuget server. This solves some of the updating problems by maintaining multiple versions of the same library, and provides a nice interface to update references in all projects. But this is a somewhat more complicated solution, so I would not recommend this for new developers.
I currently have a library which was created in a silverlight application for its use. But Now we are switching over to WPF. So i don't know how would i convert the library to a wpf library. Would i just have to copy all the file in a new project(wpf class library)
As you can see when i reference this silver light library in my wpf project. It gives me a warning.
As the message says, you can't use a project compiled to target Silverlight as a reference for a project targeting some other .NET framework family. You will need to compile a separate assembly compatible with the .NET framework family you're using (i.e. a desktop version). This will require the creation of a whole new project (I'm not aware of a practical way to have a single project target both Silverlight and desktop .NET).
Note that the new project can use the same source files as the original Silverlight one. After creating the project (which you should create as an "Empty Project"), you can add the source files from the Silverlight project, by using the "Add Existing..."/"As Link" option for adding items to the project. Adding the source code as links will cause the new project to reference the original .cs files in their current location rather than creating a new copy of them for the new project.
Note also that your Silverlight code may or may not be 100% compatible with the WPF API. You may have to introduce conditional compilation (i.e. use #if, and declare appropriate conditional compilation symbols, in the projects' settings "Build" tab) so that you can provide correct code for each platform in each .cs file.
Related topics (there a lot of duplicate questions involving adding existing items as links…though many of these involve multiple solutions, not just adding items to a new project):
Share c# class source code between several projects
How do I keep common code shared between projects in c#?
Adding Existing Files To Different Visual Studio 2010 Project
Is it possible to statically share code between projects in C#?
Updating classes used in multiple projects?
Make reference to C# code from multiple projects
Share .cs file among VS 2010 C# projects
How to include source files of one project in another project?
Suppose I have a bunch of namespaces:
SuperNamespace.namespace1
SuperNamespace.namespace2
SuperNamespace.namespace3
SuperNamespace.namespace4
...
SuperNamespace.namespaceN
Each namespace has its own project and each project creates its own dll file:
SuperNamespace.namespace1.dll
SuperNamespace.namespace2.dll
SuperNamespace.namespace3.dll
SuperNamespace.namespace4.dll
...
SuperNamespace.namespaceN.dll
I like this design because it allows developers to use only the code that they need. Sometimes having a bunch of dll's can be a bit cumbersome and annoying. I would like to create a SuperNamespace.dll which contains all of the namespaces. That way, a developer has the option to use what he/she needs or just take the big dll file, i.e. SuperNamespace.dll containing all libraries:
SuperNamespace.namespace1
SuperNamespace.namespace2
SuperNamespace.namespace3
SuperNamespace.namespace4
...
SuperNamespace.namespaceN
Is there a way to do this in a C# Visual Studio 2010 solution?
I would simply create one large project with all sources unless there are other reasons to keep separate assemblies.
In later case I'd still create one project that includes everythin in addition to small projects before going ILMerge route as Mith Wheat suggested. You can easily create new project from a lot of files using File->New project from source (may need higher version of Visual Studio for that, defintely not Express ones).
There is no restrictions how many C# namespaces can be used in in one assembly (DLL). You can find many examples in .Net framework itself - i.e. many of System.* namespaces come from the same assembly.
Opposite is true also - same namespace can come from multiple assemblies.
Note that in compiled code there is no such thing as "namespace" - it becomes part of class/struct/enum name.
I would like to keep version in my .net applications and let the .net to manage it. I don't really understand how it works. Is the version number per project ? How .net manages versions? If anyone could please explain it briefly i will be grateful.
What I usually do is to keep a SolutionInfo.cs that contains all the attributes that are common for the projects of my solution, for example the version-number. I keep this file in the solution root.
I then link that file into the project (right click the project and Add->Exsiting item... -> Add as link (the little arrow on the add button)).
I then can increment the version number in a single place and it will be updated in all the projects that links that file.
For more information on that for example see: http://jebsoft.blogspot.com/2006/04/consistent-version-numbers-across-all.html
The version number is per-project (.csproj file), so per built .dll or .exe file. The version number is embedded in the .dll or .exe, and can be viewed using (for example) Windows Explorer by right-clicking on the file and selecting Properties.
MSDN contains an explanatory article about how to use AssemblyVersion and AssemblyFileVersion at http://support.microsoft.com/kb/556041
[AssemblyVersion] is a very big deal in .NET. Every type in your program is imprinted with the assembly version, it is part of the type identity. In other words, when the version of your type changes then you should also change the assembly version. This forces all other assemblies that use your type to be recompiled.
One thing you can do is to let the build system automatically increment the version. You can't call this 'managing the version' by any stretch of imagination. Because now just rebuilding your assembly, even without making any change in the source code, will make your assembly incompatible with other code that uses the types in that assembly.
Clearly this can only work well if you recompile all the code in your solution.
Well, that's not great unless you like sword fighting. Furthermore, sometimes you want to make a simple bug-fix in your code. The result is an assembly that's still 100% compatible with the original version. And you don't need nor want to recompile everything else that uses it. You just want to send that one assembly to your customer. Clearly that can only work well if you don't let the version increment automatically.
So what you really need is some kind of tool that can magically determine that your source code, the publicly visible part of it, is no longer compatible with a previous version. Or the changes you made to the non-visible part of it are changing the behavior of the code too much to disallow other code that use your types to continue to use it without some changes in their code.
There's only one tool that I know of that can do this, the one we have between our ears.
A lot of my projects contain the Castle/NHibernate/Rhino-Tools stack. What's confusing about this is that Castle depends on some NHibernate libraries, NHibernate depends on some Castle libraries, and Rhino-Tools depends on both.
I've built all three projects on my machine, but I feel that copying the NHibernate/Castle libraries is a bit redundant since I built Rhino-Tools using the resulting libraries from my NHibernate and Castle builds.
Right now, I include all projects in seperate folders in my /thirdparty/libs folder in my project tree. Should I simply just have /thirdparty/libs/rhino-tools in my project and use the Castle/NHibernate libs from there? That would seem to make logical sense in not duplicating files, but I also like having each project in it's own distinct folder.
What are your views on this?
This is one of the problems that we're trying to tackle in the Refix open source project on CodePlex.
The idea is that Refix will parse all the projects in your solution, and before your project compiles, copy the necessary binaries from a single local repository on your machine into a folder within the solution tree and point the projects at them. This way, there's no need to commit the binaries. Your local Refix repository will pull binaries from a remote one (we're setting one up at repo.refixcentral.com), and you can set up an intermediate one for your team/department/company that can hold any additional software not held centrally.
It will also try to resolve conflicting version numbers - Visual Studio can be too forgiving of mismatched component version numbers, leading to solutions that compile but fall over at run time when they fail to load a dependency because two different versions would be needed.
So to answer the question "how do you package external libraries in your .Net projects", our vision is that you don't - you just include a Refix step in your build script, and let it worry about it for you.
I use a folder for each, which seems to be the convention.
Does it really make a difference if you're copying them?
What if you want to switch one out? Let's say you go with a new O/R mapper. It will be much easier to just delete the NHibernate folder than to selectively delete DLLs in your Rhino-Tools folder.
Take this to it's logical conclusion and you won't have any folder organization in your lib folder since everything uses log4net :)
Add additional probing paths to your app.config files to locate the dependency dlls. This way your can get away with having just one copy of everything you want. Though there are some quirks to using this feature (you must create the folder structure in a certain way). Look here for more details on the tag.
I will definetly recommend having a thirdparty or vendor folder in each of your project trees. If you find it annoying to have 32 copies of the rhino-tools package, you can have a single copy of it in your code repository, and do external references to it in your project tree.
Lets say you are using SVN, you can make a repository called "thirdparty libs" and in this have versioned copies of the libs. You then make an external property on your "thirdparty"-folder in your project tree which then in turn automaticly will do a check out of your centralized thirdparty libs. This way you for instance only have to update in one place if a security or a bugfix comes out, but each project is still in command of choosing which thirdparty libs, and which versions to use.
About the deps internally in thirdparty libs, i wouldn't mind those. The first time you compile your project, and some of the libs arent copied to your bin-folder because of implicit dependencies you can add an external attribute into your bin-folder, which will then automaticly check out the missing libs. That way you still only have to update your thirdparty libs in one place.