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.
Related
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.
Is it a good manner to split a software project in different sub projects. I want to separate the different, more ore less complex, dialogs to single projects in my solution. Every dialog is build by the mvvm pattern/paradigm. Now I want to initiate the "main" project an hold the different subproject only as reference. Am I running in problems, when using unit tests e.g.?
Splitting a project into different projects is good. But it depends how you separate it. If you are putting views in one project, view models in other, model in other, then this would be really bad. Keep all UI stuff in one project and model in other.
When following MVVM, I usually have two projects. One is exe containing Views and ViewModels while second project containing Model data. There are two unit-tests projects one for application (unit-testing of viewModels) and one for data. Now here Model can further split into multiple projects depends on what Model contains.
Usually a separation of:
UI
Business / ViewModels
Data layer
is quite common and a good habbit.
For UI specific. It is usually not necessary, unless you want to expose your UI components as a external library.
This will create some overhead, and sometimes leave you with a headache. (I tried it once with pre-compiled pages in MVC: bad idea).
My personal opinion: if you're not using it as external library in different project, it's not worth the extra work. (versioning, UI-threading stuff, other unforeseen issues...)
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'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.