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.
Related
I have a solution with multiple projects each of which connects to the same DB and uses overlapping constant values that I would like to set somewhere instead of replicating manually. I have tried a variety of things online like making a custom class and linking projects to it, setting constants in a project config file (which doesn't exist like the guides claim), and so on. I've been unable to figure this out after more than an hour of searching and experimenting so if you have any ideas, let me know. The structure looks like this (the blue-underlined stuff are some of the projects in the list):
You can make another project under the solution to contain your class.
All the other projects can then reference that project, meaning the same functionality will be available in all the other projects without having to duplicate anything.
I will extend the previous correct answer with some more information.
Your solution structure is something to think very carefully as it is a combination of application design/architecture and leads to extensibillity, scalability and future maintainability.
Take for example the following article Common web application architectures.
You can see the Clean Architecture (AKA Hexagonal) which leads to specific projects withing a solution
You can see older designs where the DB access would go into a project called ..DAL
Simple projects can use the second one, more business rich ones the first or something in between.
Check this this article on shared code projects to see about net standard projects
So the above was helpful, but far more complicated than it needed to be. Apparently other answers I'd seen actually work, but it took reading a bunch of other pages to figure out the whole puzzle. The working steps are:
Create a class with public parameters for your constants
Place that class somewhere in your solution space. When I created it on the solution, it was placed in "Solution Items" in my tree (which is the root folder of the solution on the file system).
Right click each project and ADD>Existing Item and point to the class. The KEY (that was missing from most things I read) was that the "add" button" has a drop-down arrow that lets you change it to "Add as link"
In each project (after adding as link to the file), you can directly reference the values as NAMEOFCLASS.NAMEOFCONST but ONLY if you declared them as public const SOMETYPE SOMENAME. Without the const, it's not able to directly reference the value
Note that this fix is in the .sln file itself and needs to be part of the commit or it won't have any effect. It would be nice if you could use "include" or something to bring in a file a folder one level up, but here we are.
Now I programmatically generate sources and create some classes before compilation and obviously add it to project in solution. Maybe it is possible to "silently" add classes before compilation without creating .cs files in disk and not showing these classes in Solution Explorer (maybe using Roslyn).
EDIT: I must not use any runtime code generation.
You can put the classes in a separate DLL (class library). When you create that DLL using another solution you will not see the classes in your solution explorer of the project where you include them.
Don't forget to add a reference to the DLL (class library) in your main project.
You could probably do something with MSBuild, creating a custom project target which does the work, but I've never done this.
What I have done recently which is now achievable on the DNX-based ASP.NET 5 platform, is a concept known as meta-programming. I've written a blog article about this concept specifically with examples of generating code at compile time. In my particular example, I've got a class that won't compile, but then with an introduction of an ICompileModule, I can fill in the missing method return statement at compile time.
This is possible because in DNX-based applications, the RoslynCompiler class actually supports loading instances of ICompileModule at compile time, and then running these instances before your main project compilation. This enables you to add/remove/replace syntax trees in the compilation before the compiler finishes its work.
If you're looking to develop on ASP.NET 5, this could enable you to do what you need, but I don't know how you would go about doing this otherwise.
Seems quite aspecty to me.
I asked a question which I also answered myself about engineering a compile-time solution that performs code generation for another scenario:
Getting interface implementations in referenced assemblies with Roslyn
And lastly, other examples where this might be useful, and something I've been toying around with, is the ability to generate EF-style migration classes from .sql files embedded in my assemblies. All these scenarios are now easier for me to implement on ASP.NET 5 + Roslyn.
Without knowing your use-case properly, here's an idea...
Create a VSIX that listens to an 'on build' event
Upon initialisation of the build, the VSIX creates your new classes*
The same VSIX will also listen for a 'build complete' event
Upon completion of the build the VSIX would tear down the new classes
*Your question states that the classes should not be created on disc, so the VSIX could
create the classes as a memory stream (?)
add the new class as code within existing files on disc
create the new class as a new file on disc (or cloud ?) in C:\Temp or elsewhere
the new class could be part of a partial class (either a real partial class in your application or an empty new dummy partial class)
In any case the project file would need to be auto-edited (by the vsix) to reference the new file(s). Presumably you want the project file reverted aferwards ?
And if, unlike me, you want to get down and dirty, you could always interfere with the IL, but you're on your own there !
As TarkaDaal says, without knowing why you need this it's not easy to provide a more definative answer.
My C# .NET solution files are a mess and I am trying to find a way of getting things in order.
I tried to put all close files together in the same folder I am creating for that purpose. For example, I put interfaces, abstract classes, and all their inherited classes at the same folder. By the way - when I do that, I need to write a "using" statement pointing to that folder so I can use those classes in other files (also a mess I guess).
Is there an elegant way of doing things more clean, and not a list of files that I find very confusing?
Is it a good idea to (let's say) open a abstract class file and add nested classes for all the classes derived from it?
Is there a way of telling the solution to automatically set the folder "using" statements above every class I create?
The best way is when your solution file system structure reflects your program architecture and not your code architecture.
For example: if you define an abstract class and after have entities that implement it: put them into the same "basket" (solution folder) if they make a part of the same software architectual unit.
In this case one by looking on your solution tree can see what is your architecture about (more or less) from very top view.
There are different ways to enforce the architecture vision, understanding and felling of the code file system. For example if you use some known frameworks, like NHibernate, or (say) ASP.NET MVC tend to call the things in the name the technolgy calls them, in this way one who is familiar with that technology can easily find itself in your architecture.
For example WPF force you define in code things in some way, but also you need to define byb the way Model, ModelView, View.. which you will do intuitively in seprate files. The technology enforcce you to define your file system in way it was thought.
By the way the topic you're asking for, is broad known dilema/question, not resolved, cuase the code is just characters sequence and nothing else.
Good luck.
It sounds like you're hitting the point where you actually need to break things up a bit, but you're resisting this because more files seems like more complexity. That's true to a point. But there's also a point where files just become big and unmanageable, which is where you might end up if you try to do nested classes.
Keeping code in different namespaces is actually a good thing--that's the "issue" you're running into with the folders and having to add using statements at the top of your files. Namespacing allows you to logically divide your code, and even occasionally reuse a class name, without stepping on other parts of your code base.
What version of Visual Studio are you using? One little known feature of Visual Studio is that it can automatically create the using directive when you type a class name. That would eliminate one pain point.
If I was in your shoes, I'd start looking for logical places to segment my code into different projects. You can definitely go overboard here as well, but it's pretty common to have:
A "core" project that contains your business logic and business objects.
UI projects for the different user interfaces you build, such as a website or Windows Forms app.
A datalayer project that handles all interactions with the database. Your business logic talks to the datalayer instead of directly to the database, which makes it easier to make changes to your database setup down the road.
As your code base grows, a tool like ReSharper starts to become really important. I work on a code base that has ~1 million lines and 10 or so projects in the solution, and I couldn't live without ReSharper's go-to-file navigation feature. It lets you hit a keyboard shortcut and start typing a file name and just jump to it when it finds a match. It's sort of like using Google to find information instead of trying to bookmark every interesting link you come across. Once I made this mental shift, navigating through the code base became so much easier.
Try using multiple projects in the same solution to bring order. Seperate projects for web, entity, data access, setup, testing, etc.
IF the files are in the same namespace you won't need a using statement. If you're breaking your code into multiple projects you'll need to reference the other projects with using statements.
Its up to you. Break things apart logically. Use subfolders where you deem necessary.
Not sure.
Yes, but you'll need to create a template. Search for tuturorials on that.
1) Your solution folders should match your namespace structure. Visual Studio is set up to work this way and will automatically create a matching namespace. Yes, this requires a using for stuff in the folders but that's what it's for.
So yes, group common stuff together under an appropriate namespace.
2) Yes, subclasses should probably live in the same namespace/folder as their abstract base, or a sub folder of it. I'm not sure if you mean all in the same file? If so I would say generally not unless they're very very simple. Different files, same folder.
3) Not that I'm aware of. If you right click the classname when you use it you can get Studio to automatically resolve it and add a using (Ctrl + . also does this)
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":
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.