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)
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.
I'm a beginner programmer, apologies for any stupidity.
Having come from a python background creating small projects with only a few classes, I would have all of my code in one file most of the time.
I've been learning c# recently, and I'm writing a reasonably large console application (10,000 lines +). I obviously can't put everything in one file here, but I'm not sure how I would go about separating the project into smaller segments.
The way I have done this so far, is to create a new project for each namespace within my solution, and split each class into a separate file accordingly. So far, I have around four namespaces. I have written each namespace independently, with a view to use each one going forward in other projects.
I'm at the stage now where I would like to piece together each namespace to build my console application. How do I go about doing this ?
Also, am I structuring my code in the right way ?
Also + 1, is it possible to use files located in a completely different directory within a project ?
Many thanks in advance.
When you start with a namespace, you'll usually use your company or organization name (say, "A"). If you have multiple products/projects and are creating code for that item, you'll want to add a qualifier (say "B", "C", etc., so you'll have A.B, A.C, etc.).
Then general approach is that you want to group types together in a namespace that are related. If you create a type and it is general purpose/utility/one-off solution to a common problem, you'll want to keep it in a broader scoped namespace. When you find you are creating a number of types to support some feature or purpose, you may wish to create a narrow namespace to contain those types. For example, let's say you need to write several data access components for A.B, which contains data transfer objects, data access objects, etc. You may wish, then, to put those types in something like A.B.DataAccess.
However, remember that .NET uses an OOP paradigm. One OOP paradigm is code reuse. So if you access data in both A.B and A.C, you'll do well to create reusable data access components to encourage code reuse in both projects. In that case, you may wish to have a project such as A.Common, which contains common types used by any of your products, that contain general use, generic, or abstract concepts that can be utilized in A.B, A.C, etc.
Let me try and go further with that example.
Project: A.Common (name of assembly)
Purpose: Reusable types for any project
Namespaces: A, A.DataAccess
Types: A.DataAccess.DataAccessObjectBase
Project: A.B (name of assembly)
Purpose: Types for product "B"
References: A.Commmon
Namespaces: A, A.B, A.B.DataAccess
Types: A.B.DataAccess.DataAccessObject (implements A.DataAccess.DataAccessObjectBase)
Project: A.C (name of assembly)
Purpose: Types for product "C"
References: A.Common
Namespaces: A, A.C, A.C.DataAccess
Types: A.C.DataAccess.DataAccessObject (implements A.DataAccess.DataAccessObjectBase)
That's a pretty simplistic and crude example, but hopefully it will help you visualize the relationship between assemblies and namespaces.
Some other tips:
Don't go overboard with creating namespaces, especially when creating deep namespaces (such as A.B.Something.SomeMoreStuff.EvenMoreStuff), unless it sensible. It makes it a little harder for you to find things.
Namespaces should go from broader purpose to narrower purpose. Furthermore, if you create a type in a narrower namespace that relies heavily on stuff from a broader namespace, be sure to place it under the broader namespace. e.g. A.B.Broader.Narrower.
Finally, you should continue to create only one type per source file.
Sounds more or less on the right track. Addressing your questions/structure:
1) Don't need to have each unique namespace be represented by its own project; you can (and likely should) have multiple sub-namespaces within the same project if it helps organize your classes. In your case, it sounds like each one is being programmed as its own stand-alone component, so a project for each one makes sense.
2) Your splitting each class into a separate file is good, keep doing that.
3) Not sure about what you're asking about piecing your code together. Do you mean how to go about physically referencing/linking the projects in Visual Studio or best practices to code/access your API? If the former, you can right-click the "References" item under the project and point to the project (not its compiled DLL). If the latter, there are a variety of programming patterns you can follow, but generally you'll want to abstract a nice API out of the projects so you aren't concerned by the inner-workings of your code.
4) You can definitely reference files from a completely different directory. Just right-click on the project or folder, choose "Add -> Existing Item" then browse to the file. You'll probably want to add it as a "link" so it doesn't physically copy the file: http://msdn.microsoft.com/en-us/library/9f4t9t92%28VS.80%29.aspx
Here's another StackOverflow question that goes a bit into possible solution structures: Solution: Per application, or per application suite
Namespaces help you to organize your code and provide separation of concerns. It could be done also by creating folders or separate projects. With good logic separation you can build maintainable and scalable applications.
When you taking decisions whether to create new folder, or new project you should rely on common sense. For example, creating several projects for hello world application is an overkill. Creating folder for single class is overkill too. But when you have several classes closely related to each other, consider to separate this particular concern from other application. E.g. if you have CustomerRepository, then you add OrderRepository and VendorRepository. Its good decision to highlight concern, which they are represent. Create Repositories folder and move all those classes there.
With large applications its common to separate such concerns as business logic, data access logic, and user interface. Usually classes which relate to these concerns go to separate projects. Keep in mind, that separation done to make your code easier to understand and maintain. So, namespaces should describe concerns to you and to anyone who will maintain your application. E.g. you can use three projects:
FooCompany.BLL
FooCOmpany.DAL
FooCOmpany.UI
Thats acronyms of Business Logic Layer, Data Access Layer and User Interface. There is no 'standard' names. You can use anything which will describe your code better. Here is example of project structure I usually use for company Foo product Bar:
// Assembly for business logic
Foo.Bar.Domain
Foo.Bar.Domain.Model
Foo.Bar.Domain.Services
Foo.Bar.Domain.Repositories
// Assembly for data access
Foo.Bar.Persistence.NHibernate
// Assembly for application services
Foo.Bar.Services
// Project for presentation
Foo.Bar.Presentation.Web
Foo.Bar.Presentation.Web.Controllers
Foo.Bar.Presentation.Web.Views
Btw common practice to start namespace name with name of company you are developing for. SeeNamespace Naming Guidelines. That allows to avoid names conflicts when you have two classes with same name in different namespaces.
I'll begin from last question to first. You can use files located in a completely different directory within a project. I think you go in the right way. About different namespace you can use this code
using System;
using namespace1;
using namespace2;
I have an ASP.NET application with three areas. In the root of the application is a Models folder containing a hodgepodge of classes, including two DataContexts, some Repository classes, some ViewModel classes, some helper classes, and some business logic classes.
I'd like to create subfolders for each of these subcategories and move the associated files into the appropriate subfolder. However, I am noticing that this is breaking things. For example, if I move one of the DataContexts to a DataContext subfolder in the Models folder, I find that the code in the repositories can no longer see the DataContext type.
Which must mean that the Models folder has special meaning to the system. What am I missing here? Is there some way to "sensitize" the subfolders so that the other code can still see the implemented classes and namespaces? Or am I going about this the wrong way?
Probably a namespacing issue? The model folder has no special meaning.
The ASP.NET MVC team has said something like before:
"The only reason the model folder exists is because people kept asking us where to put our model classes" ;)
When you drag and drop your files and folder, it will move the the files, but the namespaces are not updated, thus your code will break. One way is to create new file/folder and copy your code - which is a bit tedious but right way.
Another way is to use Resharper - Ctrl+Shift R, which lets you move the file and also updates the namespaces and your code will not break.
I am finding a faster way to do the same without Resharper, and when I do I will update my answer. Hope this helps!
Taking my first steps in C# I came across this post...
in VS 2019 if you refactor->move the class file you have options to move to another location
I am trying to get a handle on the best practice for code
organization within my project. I have looked around on
the internet for good examples and, so far, I have seen
examples of a web project with one or multiple supporting
class libraries that it references or a web project with
sub-folders that follow its namespace conventions.
Assuming there is no right answer, this is what I currently
have for code organization:
MyProjectWeb
This is my web site. I am referencing my class libraries here.
MyProject.DLL
As the base namespace, I am using this DLL for files that
need to be generally consumable. For example, my class "Enums"
that has all the enumerations in my project lives there. As
does class MyProjectException for all exception handling.
MyProject.IO.DLL
This is a grouping of maybe 20 files that handle file upload and
download (so far).
MyProject.Utilities.DLL
ALl my common classes and methods bunched up together in one
generally consumable DLL. Each class follows a "XHelper" convention
such as "SqlHelper, AuthHelper, SerializationHelper, and so on...
MyProject.Web.DLL
I am using this DLL as the main client interface.
Right now, the majority of class files here are:
1) properties (such as School, Location, Account, Posts)
2) authorization stuff ( such as custom membership, custom role,
& custom profile providers)
My question is simply - does this seem logical?
Also, how do I avoid having to cross reference DLLs from one
project library to the next? For example, MyProject.Web.DLL
uses code from MyProject.Utilities.DLL and MyProject.Utilities.DLL
uses code from MyProject.DLL. Is this solved by clicking on properties and selecting "Dependencies"? I tried that but still don't seem to be accessing the namespaces of
the assembly I have selected. Do I have to reference every
assembly I need for each class library?
Responses appreciated and thanks for your patience.
It is logical in that it proceeds logically from your assumptions. The fact that you are asking the question leads me to believe you might not think it is rational.
In general, things should be broken down along conceptual boundaries rather than technical ones. MyProject.IO.DLL is an example of this principle surfacing in your current design. All of the IO things logically go together, so they end up in a single binary. Makes sense.
Breaking things down into namespaces based on their technical type - enum, class, etc. - is going to be a little more problematic.
The dependencies problem is the same one you'd have breaking one class up with many and it is resolved using the same technique: inversion of dependency. Where two things seemingly need to depend on one another, add an intermediary thing that represents the contract between the first two. This can be abstractions, constants, mediators etc... whatever you need to make it so that instead of thing A depending on thing B and thing B depending on thing A, you have things A and B depending on thing C.
does anyone know of a way to split all classes in one solution into multiple files?
The point here is that I've inherited a project in which a few hundred files contain a thousand or so classes...
I'd like to be able to get to a 1 file per class approach..
Using resharper I can easily do this manually, but I'm guessing there must be a better way?
Kind regards
Frederik
You could try one of the ReSharper 5.0 nightly builds which allow you to do it across your whole solution. You can revert to ReSharper 4.5 (or whatever version you are using) afterwards.
GraemeF's answer is correct, but when you do that refactoring chances are you'll lose all source-control history for the existing classes. This might not be a problem for you (especially if the system you've inherited wasn't source-controlled!) but I've often found that line-annotated views of a class are very helpful for determining the intent behind a particular line.
ReSharper has the Ctrl-T shortcut to jump to a type name, and holding down Ctrl makes types clickable; that might be another way to solve your problem.