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.
Related
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;
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Namespace/solution structure
If I am creating a large C# app, should I keep it all in one project?
I plan on having a data layer and GUI layer. Should these be in one project or should they be split up into two projects? At this stage I think it should all be in one project, because you can just have a separate folder of classes that represent the data layer and instantiate them when needed.
Let's say I had a separate project for the data layer, what should this project (and therefore the DLL) be called? I am not going to call it <ProductName>_DataLayer.DLL. You never see that.
Are there any other important issues? Is it important to keep the size of the main .EXE down?
My personal favorites on the topic: Scott Hanselman, Mike Roberts
You should make these layers as separated projects inside the same solution for example the data layer would be a Class Library project and it might be named YourProjectName.DAL for example ProductName.DAL.DLL or DataLayer
Data and GUI separation is always recommended, you never know what you'll need to do with the data layer in future.
I'm using the .Data .UI naming conventions, and it's fine.
I would definitely keep separate layers in their own projects. Depending on the size of the application, I would also recommend looking at breaking it down further into logical groupings based on functionality.
You can call it whatever you want. You can set the assembly name to be different than the project name in the Properties window of the project.
The consideration you have to make is whether you want to reuse the datalayer between multiple projects. If the answer is yes then you should put it in a separate project.
If no, it might still be wise to separate it from the GUI simply just in case a scenario comes up you didn't think of. (e.g. you decide to create a webservice)
Naming:
I prefer DATA and UI for naming conventions.
If the solution becomes really big, you can consider using 'solution folders'.
The more simpler way is to have all projects in the same solution.
But if you have a lot of project - the projects which were created a long time ago and are not modified (or modification is vary rare) - is better to exclude them from solution, move DLL's to some common folder and use as dll references from the solution.
For name we're using dot separated - for example <project>.dal.dll
Different projects within the same solution is a good way to do it, but really depends on how the project will be used.
At one point it was common to have a ProjectName.UI > ProjectName.BLL > ProjectName.DAL architecture, then create a Model project to define data contracts to move data between the layers.
BLL = Business Logic Layer
DAL = Data Access Layer
Each layer is compiled into different assemblies, with an EXE for your interface. The size of your compiled EXE isn't really a concern, but more getting the architecture right - if you have a separate project for each layer it will make your deployment more manageable.
Now it is more common to use the Repository pattern architecture, which lends itself well to using ORMs. It you want testable, component based code that is easy to develop and refactor you should definitely look into using repositories.
I always run into a problem where my projects in Visual Studio (2008) become huge monstrosities and everything is generally thrown into a Web Application project. I know from checking out some open source stuff that they tend to have multiple projects within a solution, each with their own responsibilities.
Does anyone have any advice for how to refactor this out? What should be in a separate project vs. part of the web project? Can you point me to any reference materials on the subject, or is it just something you become accustomed to with time?
Organize your project cleanly into namespaces. Namespaces should not be too big, not too small. Make each namespace have a public "interface" (i.e. a set of public classes) and don't access internal implementation details of the namespace from other namespaces. Different namespaces usually address different parts of an application, e.g. you'll have namespaces related to UI, business logic, helper functionality, etc. The Framework Design Guidelines have some good suggestions how to design namespaces.
When you feel that your project grows too large, simply identify sets of namespaces that are clearly related to each other and move them to separate projects. Since other namespaces already just use the public interface of the moved namespaces, refactoring the namespaces into new projects is merely a file-move-operation.
Start from the bottom up (your simplest classes that don't depend on anything else besides the Framework) and see if you can isolate the dependencies into functional units. For instance, if you have a bunch of data or business logic classes that reference each other, but never reference any of your UI classes, then you have a candidate for splitting off into another project. If you can't find clear separation points, then you have a design problem and should probably do some refactoring.
I also agree that using namespaces is a good place to start. Even within a project, you can often isolate or minimize dependencies in a way that naturally groups classes together. Putting them in the same folder reinforces this grouping as a functional unit and may really help the poor guy who has to maintain your code in the future. Trust me, I try to think about that poor guy because, on more than one occasion, that poor guy has been me. Twas a small comfort that the person who wrote the code had the same name as me at the time that he wrote it.
Check out the guidance given by the Sharp Architecture project. Its ASP.Net MVC but the same principles apply to ASP.NET and other projects. The guys that put this stuff together are smart I generally use their advice as the default and only stray when I have a good reason.
The basic tiering that they propose is
A core project for your domain objects and interfaces for accessing external services (including persistence).
A data project that depends on core and implements all the interfaces for accessing persistence
An application services project for supporting application-level concerns such as logging or login validation. This only references core.
A web project that holds only views.
A controllers project that holds your bootstrapping code and the code for coordinating your web layer, domain.
In the case of an asp.net app I like to use the mvp pattern which would basically mean the
Web project holds your WebForms and codebehinds which should contain only the minimum amount of code required to redirect to the presenter. You probably also will need to put your bootstrapping code in there. This is due to an ASP.Net limitation and you should NOT reference any of that stuff from your codebehinds.
Controllers project is replaced by a presenters project. The big difference here is that somehow the presenter has to be instantiated by the WebForm rather than the other way around.
You can also try to check out the ASP.NET MVP project.
I am writing a web application which will include several parts - interactive calendar, todo list, managing finances,...
How should I design my solution? I thought something like this: each part has 3 projects (main project, DAL, BLL).
So in my case I would have 9 projects in my solution:
List item
Calendar
CalendarDAL
CalendarBLL
Todo
TodoDAL
TodoBLL
Money
MoneyDAL
MoneyBLL
Would this design be OK?
Also: where should web.config be? In it I have a connectionString which I would like to call from all DAL projects. Now I had web.config file in Calendar project and when I wanted to create dataAdapter in CalendarDAL with designer, I couldn't use existing connectionString from web.config.
Thanks
Unless you need to be able to separate and use the logic of this code in multiple applications, there is really no need to separate it into that many projects. It adds complexity but doesn't really add value. I used to separate the general BL library from the DL library but realized I wasn't really getting anything out of it...and I was making some things more annoying in the process. What is most important in separating code is the logical separation, not the physical separation into separate dlls.
Also, instead of breaking this up into separate web apps, put them in one. It will be a lot easier to develop and deploy. This allows you to use one web.config. If they are separate websites then create different web projects. If they are not, then don't.
[Edited]
One thing I meant to add, which is important, is this: The question of how you should design this is actually too general to really come up with a real answer. Those thoughts are just my general thoughts on project organization, which is what the question really seemed to revolve around.
In my opinion a good, layered .Net application architecture should have the following projects (structure) in the solution:
Presentation layer: Here's where the web.config resides, your ASPX pages and user controls (ascx)
Interface layer for the business logic layer: A layer containing exclusively interfaces of your business logic layer
The business logic layer classes: The classes implementing the interfaces of the interface layer (point above)
Interface layer for the data access logic: Again, exclusively interfaces of your data access layer
The data access layer classes: The same as for the business layer; the implementations of the interfaces of the layer before
This sounds quite complicated but represents a good separation of the logical layers. So for instance you could exchange your business logic layer or more probably (and realistically) your data access layer DLL without changing anything above since everything is separated by the according interface layers from each other.
To what regards the separation of the different projects you mentioned (i.e. Calendar, Todo, etc...) I'm not really sure. The question you have to pose is to whether these things are independent applications or whether they belong together. Modularization is important, but has to be thought of very well. What I for instance would separate is like when you have a project with different kind of UI's, one for the Administrator and one for the normal user. Here it could make sense to just exchange the presentation layer, the rest below could remain the same. So you could for instance put the admin presentation layer + the other logical layers below inside a solution and the user UI presentation layer + the (same) logical layers in another solution. This may make sense when different development teams are developing each of the solutions.
In your case it seems to me more of being a single project, so I would just group them internally in different user controls/namespaces, but not create a project (-> DLL) for each of them. This adds just complexity without any major advantage.
read up on MVC or nTier programming.
three basic layers:
your view: the aspx web pages
a controller: allows the view to interact with the model (kinda like encapsulation) it's just one class that acts as a go between.
a model: in here is your database/xmldata and your functionality. this is where the magic happens.
work in increments. first make the most basic of websites. then add functionality (one new feature at a time) , test it then move on.
Honestly this doesn't sound right at all.
You description of the components isn't really all that...descriptive (can you tell us what you're system does?), but it sounds to me like what you really have is 4 component classes (List, ToDo, Calendar, Money) in one project, one (always one) DAL project, and possibly a business logic project. Probably you'll require others. I can't think of any meaning of "DLL" which makes sense in this context.
Nine projects for four logical objects is way too much. Separate code projects by what is logically associated: less is more.
I'm having a couple of problems with circular reference/dependency that I've been sitting on all day. Something must be wrong with my thought process, I just don't get it.
Here are my projects:
Flip.Main (ASP.NET MVC)
Flip.Domain (C# DLL)
Flip.Services (C# DLL)
Flip.Utility (C# DLL)
Current References/Dependencies:
Flip.Main -> Flip.Domain, Flip.Services, Flip.Utility
Flip.Services -> Flip.Domain, Flip.Utility
Flip.Domain -> Flip.Utility
I wanted to structure my project in a way that my services project has all services, my domain project the model, repository and 'fluent' extensions to query the model, and the main and utility project are pretty much self explanatory.
Problems encountered:
1) I have an EmailService in my Flip.Services project, which needs to send out localized emails. All localization is done in Flip.Main's App_GlobalResources. No idea how to get the strongly typed emails and other localized resources now to my service layer as Flip.Main already depends on the service layer and therefore I can have it depend back to the Main project.
2) I have business classes, e.g. CustomerSearchFilter which represents a strongly typed search query. I want those business classes outside of the Flip.Domain project because they are not part of the domain model. However, in my CustomerSearchFilter class I have domain class instances (e.g. CustomerGroup) so it needs to know about domain classes. At the same time my Fluent interface in my Flip.Domain project needs to know what CustomerSearchFilter is so I can apply it to my IQueryable interface. Circular reference again.
3) I have a custom [AuthorizeSessionState] attribute which I use to decorate specific controller actions in my ASP.NET MVC Flip.Main project. This is an ActionFilterAttribute which needs to instantiate my SessionService who resides in my Flip.Services project. I can't put this into my Utility class though (because Flip.Services already references Flip.Utility). I don't think they should be in Flip.Main either - do I have to make another project for this!?
(20 more)
I feel like I'm making a mistake somewhere down the line, especially when I read that others usually don't encounter circular reference problems. Help?
Use interfaces for all non-trivial classes. Place interfaces in a different assembly from implementation.
The question comes down to what you separate by namespace and what you separate by DLL. If you have a good reason to keep EVERYTHING modular, you have to work really hard. But if each of these dlls only have a class or two in them, perhaps you could merge them together?
Take a few minutes and sort out the procedures ... create an identifier for each project (FM, FS, FD, FU). List each publicly accessible procedure on a page and then add an identifier for a project, if that project uses the procedure ...
Then you can see which procedure needs to be in (or accessible to) which project.
Hope that helps!
You can put your localized email strings in Flip.Services. The downside is that you have two places to maintain localized resources. You can also have a separate dll for all your resources to minimize the place to edit resources.
You have to move the fluent interface to an other dll or make CustomerSearchFilter part of the domain.
You will need to add more projects or rearrange your structure and use namespaces to create the separation.
It sounds like your building on concrete implementations instead of interfaces/contracts. As Ima suggests define interfaces that describe what a certain class should be able to do. Use this interface when you declare properties, parameters and the like. Keep the interfaces separate from the implementaion and both the implementation and the projects that uses the interface can reference the interface project.
You then get the nice option of using dependency injection making your code easier to test as an a side
In the "tiers" of a domain, repositories and services live at the same logical level, above the domain in an infrastructure role. I would suggest moving your repository implementations (queries, etc.) outside of the domain itself. That solves #2 at least.