Structure of a Medium-Large scale project - c#

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;

Related

why use a dll instead of a class

i joined a new project where they use c#.
I noticed that several dll's were being add in the references
From my knowledge and the e-learning that i have done, after building a class(which has some Methods & data), a DLL is generated.
Now in a new project, the class that just got converted into a DLL is added as a reference so that the functions defined in it could be called.
So, now my question is:
1) what is the need for converting the class file into a DLL file. Even it were a Class file, I could still be calling the functions defined in it by adding its namespace at the top of the code
2) If After adding the reference of the DLL , I deleted the entire contents of the project, leaving only the dll untouched(and in the same place), would the class using this dll still work
Separating your code into different projects (each of which will create a separate assembly) has various benefits:
It makes the structure of your code clear. For example, it can separate your storage layer from your business logic, and also from your user interface.
It allows reuse: two different user interfaces can refer to the same assembly containing the business logic, for example.
It allows greater encapsulation: classes which are only needed within their own assemblies can be declared as internal (which is the default for top-level classes in C# anyway) which means code in other assemblies won't even know about them. If all your code is in a single assembly, all those classes will "know about" each other.
Now choosing just how many projects to have is a balancing act - I've certainly seen applications where this has gone much too far, with lots of assemblies containing just a single class. If you have a large number of assemblies, that becomes a headache in terms of project and reference management. However, having too few assemblies makes it harder to reuse that code cleanly.
In addition to Jon Skeets answer, I'd like to add "updateability" as well. For me, this has two benefits
one is that the build time becomes smaller if only one project needs to be rebuilt
and second, pushing to "release" could be limited to a few dlls instead of one major .exe.
The first might not be a big deal in C# since projects build pretty fast, but for instance switching to C++ would be a big impact, since C++ code take a long time to compile.
The benefit of Separating is that it lets you change the internal implementation without breaking client code. It doesn't protect you if you decide that you need to change the interface to your code, but that's a different matter.
they can reuse their code. but if they use classes every time they need to implement these classes ( in the best way copy and paste all codes )
when they use dlls in instead of classes they can update all project easily by just Update one or more dll although if you use class in multiple projects you suould modify all classes in all projects.
I might add that a class is a language construct while an assembly is a deployment package.
Already in UML those are two totally different things.
http://en.wikipedia.org/wiki/Package_(UML)
When approaching the new idea of subdividing a solution, projects may be seen as "places" in which to put namespaces (i.e. folders) and classes (i.e. files).
It will take some time until you realize that a project best fits the concept of stratum (or layer) which is an architectural separation of a system.
When stratifying a system, you'll realize that the most crucial problem to tackle are the dependencies between strata (which would be the references to projects or dlls).
There cannot be loops but more important, you should study OCP (Open-Closed principle) and ISP (Interface Segregation Principle) and DIP (Dependency Inversion Principle) of SOLID:
http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
At that point a new question will emerge. How can you know which classes depend on each other or do not? You may draw class diagrams, but there is a conceptual approach to the problem. Over the years it becomes a "practice" of designing systems. The concepts are described for educational purposes in GRASP:
http://en.wikipedia.org/wiki/GRASP_(object-oriented_design)
The most important parts of GRASP for stratification are "Low Coupling" and "High Cohesion". In other words, you should batch functionally very similar classes in a stratum and separate through the stratification classes that functionally are not very much related to each other.

Arranging solution files

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)

Disadvantages of separating code corresponding to independent blocks with different namespace rather than a different project in the same solution

I am working on a project in which my entire team is facing the following problem, please help me to discover the issues associated with the approach which we have decided to follow so that we can save ourselves beforehand :)
We have decided to separate out the entire code of our application into just three projects in a single solution.
1) One project will contain entire UI
2) Second will contain entire business logic. In this project the code corresponding to different modules of our application will be separated via different namespaces rahter than having separate project for each modules or dependent modules.
3) The third project will contain all the common code
I am still able to see that there might be some problem in future if we put the entire code in second project under different namespaces in a single dll rather that splitting it in different dlls/projects.
We are working on a WPF based application.
Please help!
Shahil Gautam
I am still able to see that there might be some problem in future if we put the entire code in second project under different namespaces in a single dll rather that splitting it in different dlls/projects. We are working on a WPF based application.
The only "problem" with doing this is that it's a bit easier to "accidentally" reference types in other namespaces. If you separate into separate projects, the only way to "pollute" your type with business logic unrelated to it would be to explicitly add a reference. When it's in the same project, you can have a using statement or a fully qualified type name, and "use" an unrelated type without any compiler warnings.
I think that's a sensible choice. I general, assemblies should be units of deployment. There is no need to have 10 assemblies if they are always going to be deployed together.
One issue however is that you will have to be more careful about your dependencies within a project. When separating things into different projects, there are physical barriers for introducing inappropriate dependencies, while now you will have to be more conscious about this. A tool like ndepend might help you find suspicious dependencies in your code.
I do not see why you would want to have multiple namespaces within your business logic project.
There are two possibilities:
ONE. All of the types that you define in the project have different unqualified names.
In this case, separating the namespaces would have little purpose. The only benifit would be that the intellisense object selections would be shorter and clearer when the usings to the other namespaces are omitted. Putting the types into separate projects would accomplish the same thing just as well, and offer better separation of concerns.
TWO. Some of the types in the different namespaces have the same unqualified names.
In this case, confusion could easily result, whenever a using from another namespace is added in an unsuccessful attempt to reference a type from another namespace with its unqualified name. If there is no danger of that happening, then, once again, why not put the objects into separate projects, since, clearly, the lines between the domains are sharply drawn?

Code Organization Connundrum: Web Project With Multiple Supporting DLLs?

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.

Winforms - best directory / project structure

Wanted to see peoples thoughts on best way to organize directory and project structure on a project / solution for a winforms C# app.
Most people agree its best to seperate view, business logic, data objects, interfaces but wanted to see how different people tackle this. In addition, isolate third party dependencies into implementation projects and then have interface exported projects that consumers reference
View.csproj
BusinessLogic.csproj
Data.csproj
CalculatorService.Exported.csproj (interfaces)
CalculatorService.MyCalcImpl.csproj (one implementation)
CalculatorService.MyCalcImpl2.csproj (another implementation)
Also, in terms of folder structure, what is better nesting:
Interfaces
---IFoo
---IData
Impl
---Foo
---Data
or
Product
---Interfaces/IProduct
---Impl/Product
Foo
---Impl/Foo
---Interfaces/IFoo
All trying to push for decoupled dependencies on abstractions and quick ability to changed implementations.
Thoughts? Best practices?
For me it depends on the model I'm following. If I'm using MVC it would be
Project
-Models
-Controllers
-Views
Or for MVP it would be
Project
-Models
-Presenters
-Views
Under the views I seperate them into namespaces relevant to the controllers, i.e. if I have a controller to handle inventory transactions I might have it as
Project
-Models
--Inventory
-Controllers
--Inventory
---TransactionsController.cs
-Views
--Inventory
---Transactions
----EditTransactionsView.dfm
For interfaces I put the interface in the same directory as the implementations.
Bit of a late answer but may as well chime in.
I have been personally using folders based on the actual type of item it is. For example:
- Project
+ Forms
+ Classes
+ UserControls
+ Resources
+ Data
So I end up with:
new Forms.AboutForm().ShowDialog();
Controls.Add(new Controls.UberTextBox());
We usually keep SourceSafe projects, project names, namespaces and directory structures in sync.
For example, given our company name as XCENT the SourceSafe structure and the corresponding directory structure for App1 looks like:
\XCENT
\XCENT\App1
\XCENT\App1\UI
\XCENT\App1\UI\Test //test harness for UI
\XCENT\App1\Data
\XCENT\App1\Data\Test //test harnesses for Data
etc.
The UI project is named XCENT.App1.UI.cproj, and the classes within that namespace are XCENT.App1.UI
We work for many clients as well so work specifically for them is prefixed with their name. Client1\App1\UI, etc.
Everybody in our firm uses the same conventions and it is immediately clear where everything fits.
If it makes sense to segment logical spacing further we do so. Such other segmentation includes .Export, .Import, .Reporting, .Security, etc.

Categories

Resources