Task: reuse C# code in different projects but without project referencing (don’t want extra dll/references just because of a small utility class).
There’re 4 projects, one of them contains utility class which is currently source-code-linked by other 3 projects.
Problem: once one of the projects starts referencing one of others (for some other needs), the compiler starts complaining (obviously) that there’s the same class (with the same namespace) in these projects.
Are there any solutions other than to move the class to separate project or to make 4 copies of the class for each project and maintain them separately?
I wonder is there a way to source link files so that the class inside a file gets project-specific unique namespace…
I wonder is there a way to source link files so that the class inside a file gets project-specific unique namespace…
Well you could use preprocessor directives:
#if PROJECT_FOO
namespace Foo
#elif PROJECT_BAR
namespace Bar
#elif PROJECT_BAZ
namespace Baz
#endif
... and then link the file into each project, defining appropriate symbols in the project properties.
But I would thoroughly recommend against it. It's horrible, and it's certainly not how C# was designed to be written.
Just break it out into a separate project - you're bound to find you want more and more code like this anyway.
To the question:
"Are there any solutions other than to move the class to separate project or to make 4 copies of the class for each project and maintain them separately?"
The short answer is: no, there isn't. Or at least, there is no elegant way of doing that.
The right way is indeed to make it part of a referenced project. But you don't have to make a project that will contain JUST that utility class! Instead, make it a project holding multiple simple utilities with as little dependencies as possible and share it across your solutions. Much easier and cleaner this way.
Related
I would like to create utils class library (eg, logging, etc).
I want to use the utils solution in several indepandent applications.
I'm using source control of course...
does that mean I should manage utils solution (holding the utils class library)
and also seperate solution for each application ?
what do I have to do to use the utils class library from ApplicationA solution
can ApplicationA solution also include the utils solution (eg, go to definition works ?)
if that is possible, does that mean that any change proggrammerA apply to utils library via ApplicatioA solution, also affects ApplicationB solution using the same utils class libray
what do we to do when we fix a bug in utils solution ?
how does the fix bubbles to ApplicationA and B .
It sounds like you have the possible approaches identified already:
Develop and manage your utility library independent of any specific application.
Advantages: no need to manage multiple versions, updates done in one solution don't impact/break other solutions
Disadvantages: the Utilities assembly is essentially a closed box, a component your applications are consuming, the same as any third-party or .NET framework assembly.
Put your Utilities library project into source control, and have the solution to each of your applications include it as a project reference (this is possible, to answer your question above).
Advantages: Utilities library is kept up to date in all projects, and can be stepped into during debugging, etc.
Disadvantages: Changes made to Utilities as part of development in one project may break it for another. Also, this may add issues with versioning, you may need to roll back changes for patch builds, etc.
Create a new copy of the Utilities library for each project
Advantages: no issues with build, debug, deployment or versioning
Disadvantages: changes made to the Utilities in one project are not reflected in others, and must be manually copied over if needed.
At the end of the day, there is no one correct answer; it depends on the stability of your utility methods, how often they need to be changed, and how often you will want/need to debug into them.
In most cases, I find that it is more convenient to just create a new copy of the Utilities class library for each project. They end up being somewhat different eventually, but the ease of maintenance makes up for the lack of consistency across all projects. If you had a very complex set of utility classes that encapsulated some portion of your business, you would probably want to go the other way and maintain it independently.
I think you need to read up on how to distribute APIs for consumption. You should keep this as a separate project. Version it how you would something you release to the public. If you make a change in the utils and you need it in AppA, thats fine, just know that until you test with AppB you will either need to use a branch or the old version of the util class.
I wrote some classes that I use with many different projects.
For example, I use Library.Controls.FlatButton.cs almost in every project.
The problem is when I add this as an "existing item"; the class gets created/copied in my soultion folder everytime. And each time I edit/update the contents of that class, I have to update all the Library.Controls.FlatButton.cs files in every project folder.
I need to be able to edit a single source of FlatButton class and when I compile/build a project (that uses the class file) gets updated to the new version of that class.
Question 1: Is there a way to do this?
I know that I can gather all these classes in a library project (Library.Controls) and add it to each application solution as a dependency.
Question 2: Is this the only way to work from a single source of common library files? And if I do; will all the classes in the Library.Controls namespace get compiled with every application, even if I've only used this FlatButton class in the project?
Hope this is clear for you..
thanks
I'd rather go with the approach of the shared library and add them as references to your client project.
If you don't want to do this. You could add the file as "Link". In Add existing item, select Add as Link instead.
Yes, a class library is the way to go and yes, since the whole class library will be referenced from your applications, all the classes will be available to it.
However, the fact that all the classes are available is not a bad thing, since they're in a separate class library it won't make your applications harder to understand (since the amount of code in those applications will stay the same), it might just be that you use up a little bit more hard drive space, though if you really worry about that you could put the class library in the GAC so that all apps reference the same copy of the library, though you'd better research this first to make sure that it's suitable for you.
Alternative way is to add FlatButton.cs file "As Link":
I have a set of methods that do some utility work over SQL connection, and until now these have been copied over from project to project. But as time goes on, project numbers have grown and I need to keep these methods in sync in case I find a bug or need to update it.
I have managed to get it to the state that SQL access class is a partial class, one part is specific for project and contains wrappers for a specific database. The second part is the common one and contains methods that are used in all project-specific databases.
The problem is that now I would have the "utility" class copied over 8 projects, with the same content, but in different namespaces. In C/C++ it would have been simple, because I would just have #included the contents of the file wherever needed. What should I do in C#?
Separate out the class so that you can have a complete class containing all of the common code, in a common project. Use a common interface to represent the bits of functionality which will be project-specific, implementing that interface in each project and passing an instance of the interface into the common code where necessary.
As Jon says, a library assembly is a good idea.
There are some situations when an assembly reference doesn't lend it self to the requirements so, if creating a library assembly is not an option, it is possible to use a feature easily overlooked in Visual Studio, adding an existing file as a link.
This would allow you to maintain the common part of the partial class in a file that is available in all your projects.
The only restriction is that a relative path is used to reference the file.
The only problem I have had with this strategy is with the open source Mercurial scc provider. When removing a linked file from a project, the underlying file is deleted. Quite annoying but this may not be an issue for you.
Update: The linked file bug in the VS Mercurial SCC should be fixed in the next release.
How should I divide source files into projects (within one solution) to
be able to use common classes in more relatively independent apps,
avoid lots of dlls needed (preferably all in one file for each application),
keep it fast?
There are working (data processing) classes, User controls, some utility classes and Forms of the application.
You can make a separate assembly by creating a class library, and use that library within other projects within your solution. Just put your reusable classes within a class library project, and add a project reference in your applications to that library.
Each time you separate out code into a separate (reusable) assembly, it does add one extra DLL (the class library project) as a requirement at runtime, but this is very minimal.
There are no real (significant) changes to performance when doing this. It is a very common practice.
You should make Class Library project(s) for each logical unit of classes, then add references to the libraries in each project that uses them.
For example, you could have a Common library that contains basic classes used by everything else, and perhaps a Controls library that contains user controls.
Each logical unit of classes can go in a namespace within the same library or in a separate library; you need to decide which.
It would be a good idea to drop the second requirement of avoiding lots of DLL's. If you put your common code into a single "common" DLL then you need to recompile every time any class is added or modified. This could then give you a terrible versioning problem that is worse than managing lots of DLL's.
You should group your common code, by the functionality they provide, into separate DLL's. So one for data access, one for user controls, one for each type of utility function, etc. Then if you have web service that accesses data you won't need to recompile the service when you add a new user control to a single DLL. Only those apps that depend on the change will need to be recompiled.
You could put the common classes into one assembly (say CommonUtils) and then use namespaces inside for the groupings to indicate how they are split
Should the folders in a solution match the namespace?
In one of my teams projects, we have a class library that has many sub-folders in the project.
Project Name and Namespace: MyCompany.Project.Section.
Within this project, there are several folders that match the namespace section:
Folder Vehicles has classes in the MyCompany.Project.Section.Vehicles namespace
Folder Clothing has classes in theMyCompany.Project.Section.Clothing namespace
etc.
Inside this same project, is another rogue folder
Folder BusinessObjects has classes in the MyCompany.Project.Section namespace
There are a few cases like this where folders are made for "organizational convenience".
My question is: What's the standard? In class libraries do the folders usually match the namespace structure or is it a mixed bag?
Also, note that if you use the built-in templates to add classes to a folder, it will by default be put in a namespace that reflects the folder hierarchy.
The classes will be easier to find and that alone should be reasons good enough.
The rules we follow are:
Project/assembly name is the same as the root namespace, except for the .dll ending
Only exception to the above rule is a project with a .Core ending, the .Core is stripped off
Folders equals namespaces
One type per file (class, struct, enum, delegate, etc.) makes it easy to find the right file
No.
I've tried both methods on small and large projects, both with single (me) and a team of developers.
I found the simplest and most productive route was to have a single namespace per project and all classes go into that namespace. You are then free to put the class files into whatever project folders you want. There is no messing about adding using statements at the top of files all the time as there is just a single namespace.
It is important to organize source files into folders and in my opinion that's all folders should be used for. Requiring that these folders also map to namespaces is unnecessary, creates more work, and I found was actually harmful to organization because the added burden encourages disorganization.
Take this FxCop warning for example:
CA1020: Avoid namespaces with few types
cause: A namespace other than the global namespace contains fewer than five types
https://msdn.microsoft.com/en-gb/library/ms182130.aspx
This warning encourages the dumping of new files into a generic Project.General folder, or even the project root until you have four similar classes to justify creating a new folder. Will that ever happen?
Finding Files
The accepted answer says "The classes will be easier to find and that alone should be reasons good enough."
I suspect the answer is referring to having multiple namespaces in a project which don't map to the folder structure, rather than what I am suggesting which is a project with a single namespace.
In any case while you can't determine which folder a class file is in from the namespace, you can find it by using Go To Definition or the search solution explorer box in Visual Studio. Also this isn't really a big issue in my opinion. I don't expend even 0.1% of my development time on the problem of finding files to justify optimizing it.
Name clashes
Sure creating multiple namespaces allows project to have two classes with the same name. But is that really a good thing? Is it perhaps easier to just disallow that from being possible? Allowing two classes with the same name creates a more complex situation where 90% of the time things work a certain way and then suddenly you find you have a special case. Say you have two Rectangle classes defined in separate namespaces:
class Project1.Image.Rectangle
class Project1.Window.Rectangle
It's possible to hit an issue that a source file needs to include both namespaces. Now you have to write out the full namespace everywhere in that file:
var rectangle = new Project1.Window.Rectangle();
Or mess about with some nasty using statement:
using Rectangle = Project1.Window.Rectangle;
With a single namespace in your project you are forced to come up with different, and I'd argue more descriptive, names like this:
class Project1.ImageRectangle
class Project1.WindowRectangle
And usage is the same everywhere, you don't have to deal with a special case when a file uses both types.
using statements
using Project1.General;
using Project1.Image;
using Project1.Window;
using Project1.Window.Controls;
using Project1.Shapes;
using Project1.Input;
using Project1.Data;
vs
using Project1;
The ease of not having to add namespaces all the time while writing code. It's not the time it takes really, it's the break in flow of having to do it and just filling up files with lots of using statements - for what? Is it worth it?
Changing project folder structure
If folders are mapped to namespaces then the project folder path is effectively hard-coded into each source file. This means any rename or move of a file or folder in the project requires actual file contents to change. Both the namespace declaration of files in that folder and using statements in a whole bunch of other files that reference classes in that folder. While the changes themselves are trivial with tooling, it usually results in a large commit consisting of many files whose classes haven't even changed.
With a single namespace in the project you can change project folder structure however you want without any source files themselves being modified.
Visual Studio automatically maps the namespace of a new file to the project folder it's created in
Unfortunate, but I find the hassle of correcting the namespace is less than the hassle of dealing with them. Also I've got into the habit of copy pasting an existing file rather than using Add->New.
Intellisense and Object Browser
The biggest benefit in my opinion of using multiple namespaces in large projects is having extra organization when viewing classes in any tooling that displays classes in a namespaces hierarchy. Even documentation. Obviously having just one namespace in the project results in all classes being displayed in a single list rather than broken into categories. However personally I've never been stumped or delayed because of a lack of this so I don't find it a big enough benefit to justify multiple namespaces.
Although if I were writing a large public class library then I would probably use multiple namespaces in the project so that the assembly looked neat in the tooling and documentation.
I think the standard, within .NET, is to try to do it when possible, but not to create unnecessarily deep structures just to adhere to it as a hard rule. None of my projects follow the namespace == structure rule 100% of the time, sometimes its just cleaner/better to break out from such rules.
In Java you don't have a choice. I'd call that a classic case of what works in theory vs what works in practice.
#lassevk: I agree with these rules, and have one more to add.
When I have nested classes, I still split them out, one per file. Like this:
// ----- Foo.cs
partial class Foo
{
// Foo implementation here
}
and
// ----- Foo.Bar.cs
partial class Foo
{
class Bar
{
// Foo.Bar implementation here
}
}
I'd say yes.
First, it will be easier to find the actual code files by following down the namespaces (say, when somebody e-mails you a naked exception call stack). If you let your folders go out of sync with namespaces, finding files in big codebases becomes getting tiring.
Second, VS will generate new classes you create in folders with the same namespace of its parent folder structure. If you decide to swim against this, it will be just one more plumbing job to do daily when adding new files.
Of course, this goes without saying that one should be conservative about how deep xis folder/namespace hierarchy goes.
Yes they should, only leads to confusion otherwise.
What's the standard?
There is no official standard but conventionally the folder-to-namespace mapping pattern is most widely used.
In class libraries do the folders usually match the namespace
structure or is it a mixed bag?
Yes, in most class libraries the folders match the namespace for organizational ease.