why use a dll instead of a class - c#

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.

Related

Structure of a Medium-Large scale project

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;

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.

Separate projects or multiple class files ... namespace best practice in C#

I'm creating a library for use with an application that I am building. I am building a name space structure similar to below.
MyNamespace.Validation
MyNamespace.Reports
MyNamespace.Transactions
MyNamespace.DataImport
etc...
Would it be best practice to create a solution with multiple projects for each sub namespace or one project with multiple class files for each sub namespace? Thanks.
There are pros and cons to both approaches, which you need to personally decide between for your own circumstance.
Pro to multiple projects:
Separate assemblies allow the compiler to provide more strict guidance, potentially preventing coupling from creeping through. This allows you to maintain the dependencies better.
Separate assemblies can be loaded as needed in other projects, potentially easing reuse.
Separate assemblies can prevent unnecessary code from being loaded into a process, since they're loaded on demand.
Cons to multiple projects:
More complex deployment, as more files need deployment (minor)
Slower build/compile, and even potentially load times from loading multiple assemblies (minor)
Personally, I think the pros far outweigh the cons in most cases. I typically will split my namespaces into separate assemblies, provided they are not related. In your case, you're working on 4 very different concepts, so my gut feeling is that splitting makes the most sense.
I would say it depends.
First, it's best practice to put each class in its own file.
If you go with one project, I would create folders for each namespace inside that project, and put the code files in the appropriate folder.
Doing the above, Visual Studio will automatically create new class files within the correct namespace
I think the real question here is this though:
If this is only ever going to be used once, putting everything in one project would make sense. However, if this code is going to be reusable, you should think if you would ever reuse just a part (or one sub-namespace) of this library. If the answer is yes, I would break apart the namespaces into separate projects, so in the future, you could only include the projects you needed.
I would go for the one solution with multiple projects.
Advantages:
- Each project can be a separate dll
- All projects in one solution for easy navigating between files
Deciding exactly how to break up your solution is subjective - and it really depends on the specifics of your code.
However, one thing is certain: maintaining multiple assemblies has drawbacks! This article is particularly good at describing those drawbacks, observing how they add costs at development time, compile time, deployment time, and runtime.
I use as few assemblies as possible, aiming for a single assembly while isolating volatile areas of the domain. When multiple assemblies are clearly appropriate or required (and they often are, particularly to enforce decoupling), I do my best to group interfaces that will change at the same time into the same assemblies.
I have usually followed the pattern with one assembly is one namespace and the DLL name is in the namespace. Easier to find what DLLs to reference

Rules of thumb for adding references between C# projects?

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.

Categories

Resources