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.
Related
I'm creating my first .net/c# website using Entity Framework as my data access layer. I've split my project into layers so that I have DataAccess, BusinessLogic, a separate BusinessObjects layer and the website itself is the UI (Pages/UserControls/Appcode folder). There is also an additional Utilities plugin project.
The EF model has gone in DA, whilst the entity creation has gone into BO. All feels good, but I'm having trouble what logic class belongs in AppCode (UI) and what belongs in BusinessLogic.
Are there any guidelines that can help me determine which side of the line things go?
App_Code is just a handy convenience for you to run code. I would advise you to avoid using that folder. Just create class library projects for all your classes, which would comprise your business logic layer. In the web project, only put pages and controls (ASCX and ASPX files). It makes the logical separation clearer.
There is a reference implementation from Microsoft Spain; which employs EF, Unity, WCF etc. But, note that this implementation may be overengineered for your needs. Before implementation, instead of copying the same structure, it is better for you to decide, which parts, concepts, patterns are useful for you and which are not.
Microsoft N Layer Reference Implementation
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 use ASP.NET in C#, I am pretty new at developing so I would like have some advice from experts :-).
Questions:
What is the best practice to organizing CLASS FILES?
What kind of name do you use?
For Web Application Project, how do you name NAMESPACE?
In my Case I am building a simple CMS. I thought the FILE structure like this:
- AppCode
- Common
- UserDataInput.cs
- ExternalLibrary
- BusinessLayer
- FrontEnd
- BackEnd
- AccessLayer
Thanks guys for sharing your thoughts with me! Bye
Naming conventions are different for everyone there are no right answers only best practices but there are plenty of wrong ones. When it comes to object oriented programming don't overkill for the sake of modularity some things, like a DataHelpers project which would be be used in your backend could be something you carry around but, say a gravatar helper class (which is an actual class under Microsoft.Web.Helpers) is an overkill simply because String.Format() and a md5 hashing method is all you need for that. It's pretty much eyeballing what you would need again in another project when it comes to modularity.
This goes without saying but, make sure what you name your methods classes make sense in the context that you work, when working with asp.net MVC what I would have a CMS.Controller project and a CMS.View project but all will be under the CMS solution where in classic ASP.net I would have named CMS.BL or CMS.Web. I wouldn't place anything under AppCode just add projects to your solutions and don't call them Common, when carrying your code across solutions they become overcrowded with *.Common namespaces.
So classify your code trough projects in terms of what they are used for and be sure to implement a hierarchy so that your classX that inherits from Xbase is under same sort of hierarchy in temrs of project when you implement this kind of a pattern in your projects you will be more sucsessfull as opposed to Xbase being under CSM.Web.Core and classX under CMS.Web which will later on pave the road to circular references.
Here is an example of a project im working on, it started as a MVC application but later turned into a prject that has winforms and everything.
As long as stuff make sense to you and you are comfortable with, you can get away with everything, like there in the solution below i have a Data.Netsis.Entities that inherits from Entities.Netsis.
Hope this helps.
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.
I've got a question about references between projects in a solution. Most of my previous applications have just had one or two projects in the Solution, but this time I want to divide the application further.
I'm starting a new Solution in Visual Studio 2008 now, and have created several underlying projects to divide the separate parts of my application.
But currently I'm just creating the different projects on a whim, and creating references between them when I need to. Sometimes I end up in a situation where two projects need to reference eachother, but that is not allowed since it would cause a circular dependency.
Are there any rules/tips/patterns I should keep in mind when I create the different projects, and linking them together?
Should I start from the inside, and go out? Having the "core" projects refrence all the outerlying projects, or perhaps go from the outside and in where the independent projects all reference the "core"? Or the third option where I have business in two projects, and they both reference a third project?
Indeed you can't have circular references, but to be honest what would be the benefit of splitting the solution into small project if you had interdependencies between all of them?
Usually before I even open Visual Studio I take a piece of paper and split my problem into logical functional areas. You can draw a Utilities assembly at the top and all the GUI's, web services and other end projects at the bottom. The Utilities project is not going to reference any other project, and the ones at the bottom will not be referenced by anything. Then you think what functionality is common for these, e.g. all GUI's can share a common UI project with common user controls and dialogs, and this UI project will reference the "object model" project, etc. The project at the bottom can only reference what is above them.
Often when it appears that you need a circular reference, you can nicely get round it by defining an interface in the lower level assembly, and providing implementation in the upper level.
Without knowing what are you exactly doing I am afraid that's the only advice I can give you.
It's a bit old-fashioned, but for help in deciding how to split into projects, you could look up "Coupling" and "Cohesion" in wikipedia.
Also, while we sometimes think of these decisions as "style" rather than "substance", we should remember that assembly boundaries do have meaning, both to the compiler and to the runtime. A couple of examples of that...
The C# compiler understands a keyword called "internal". To make the best decisions about factoring into separate projects, you should really understand the power of this.
The JIT compiler in the runtime will never inline a function call that crosses an assembly boundary, which has a performance implication. (The reason is to do with Code Access Security).
There are many more examples, so the decision really does make a difference.
I'll use a Winforms applications as an example. The pattern I have started getting into is this. The solution is called Example.
Example.Entities - This project will contain my business objects and the related heirachy of classes
Example.Dal - I put all business logic and data access logic in this project (namespace) This is the code that loads your business objects and then passes them to another layer.
Example.Gui - I put all my Winforms and GUI utility code here and my 'main' starting entry method. You could also just choose to call this project Example. I still like using the namespace Example.Gui for code separation.
Example.Test - You can put all your test code in this project.
I try to drive code into the Entities if it belongs to one of the business objects or a business object collection.
Gui will reference the Entities and the Dal (Data Access Layer).
Depending on how you write your Dal it may reference your Entities.
Test should reference Entities, Dal, and maybe Gui.
The Entities is its own Assembly dll so that you could use it in other projects. Or return them from a .NET SOAP Service.
The GUI layer should view the internals of the DAL as a blackbox. Your main app should not care how the business objects get loaded or persisted. But you should use your Test project to test your DAL thoroughly.