Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Well, first excuse me if this is not the place to do so. This is not really a question, but I got exposed to that problem, and was pretty hard to find necessary information, so I thought would be good to make a subject just for it.
This is in attention to people with a "beginner/average" level in C# like me, so please if you have some comments or corrections to make please you are welcome.
It is around a year I was developping my project, using a lot classes. But I began to meet problems when I wanted to externalise some functions.
Why externalise my functions? In order to make support easier. In fact, creating an external LibraryClass (.dll), if in future I may make some modifies on it, and send an upgrade to customer, I only need to modify, and send that library, and not all the code.
The problem is when I want to use my classes from these libraries : It is just not possible.
Then a stackoverflower (thanks Simone Sifani) gave me the good idea : I may externalize all my classes in different projects(one project for each class).
In my case the thing became a bit difficult because all classes use each other... so I will explain how I proceeded.
1) make obviously a copy of your solution before beginning, so if you do something wrong, delete all then restart(and very good exercise to understand good how these references work, after one or two tries, you will all understand).
2) Add a Project in solution for each class you want to externalize (Right click on solution/Add new project/Class Library), then check directly the version of Framework to have the same version in all solution(in my case .NET Framework 4.6.2). If you don't, you will have no error message but debugging will not work without necessary an explaination.
3) Copy/Paste all the code of the original class in the new corresponding ClassLibrary. Then add the "public" word before each class definition.
class Myoldclass
{
...
}
becomes
public class Myoldclass
{
...
}
4) Add references (this is the longest part).
Each class may require different references :
- To .NET Frameworks
- To other classes(From now I will not use the word "class" but "Library")
I personally did the following :
4-1) put in commentary all the code that requires to use external libraries, so now you will have only errors regarding references missing on .NET Assemblies and some "unexisting functions(the ones I just put in commentary).
I also advise you to take a piece of paper, in order to write for each library, the list of references needed.
4-2) Add all references to necessary .NET Assemblies (for me was the longest part of the job). After that, you may have only errors regarding non existing functions.
4-3) Begin to compile all of your libraries that don't need to use any external library. It will then generate a .dll file in its directory (bin\debug directory). I will call it Library1
4-4) In all libraries that need to use Library1, add a reference to the libraries(Project/Add/Reference/Projects->Library1.dll file). So now all the code requiring Library1 may work correctly.(I will call that one Library2)
4-5) Once you think Library2 has references to all necessaries libraries, you can uncomment your code. For this I have two solutions : Just make Ctrl+Z until the code comes back to step 3. Inconvenient is sometimes VS found errors where there are not so you need to restart it, and so coming back is impossible.
In my case, I just opened my old classes, and overwrite all the code of my library, rewrite the "public" at class definition... and then start debugging to generate the Library2.dll file
4-6) Continue so on until all libraries get all references ok(that's why it is important to write on a paper, so by elimination, you will first debug the libraries having few references needed, and finish with the most difficult ones).
4-7) On your main project, add references to all previously generated dlls.
That's all, after it for my part my project is working as before(still have some problems to read Application parameters but I am on it). I have 13 Class Library projects in my solution, that I can debug separately, and everybody can use anybody :)
Hope that post will be useful to somebody, and if stackoverflowers want to help/correct I will try to keep it updated.
What is the point of creating as much projects? In most cases I do need a "Common" library and sometimes a library for DTO. Anyhow the main reason to move out those classes into a separate project is to minimize dependencies and to avoid polluting some of your layers...
In general I use these layers/projects:
- domain classes and domain logic with domain services - here I define also interfaces, which get's implemented inside service layer
- DAL (which is actually an ORM) - so here due mapping (or due domain classes being entities) we got a dependency on the domain classes (project)
- service layer - depending on both of the 2 projects above
- presentation (application) layer - where all your projects are referenced...
Mostly I do have a solution with 6-15 projects: 4 of them are based on the layers described above, but I do got additional ones, like domain events, domain event dispatcher (for the given DI used in the project), special libraries like HTML/PDF generation or email sending (with custom logic/templates), HttpClient libraries (spacial library to create and set up chain of handlers to do: auto-login, auto retry on HTTP 401, auto-retry on some errors or logging)...
So in short: as you see, most projects I add do have a function to fulfill. They're not class based. And there's a "polluted" project with a lot of extension and utility classes, where I do try to keep things tidy by trying to keep the classes in folders, giving them meaningful names...
In your case, if those class libraries are really re-usable, i'd possibly create them as a separate project and NuGet's. But if reuse is the goal, you need to strictly hold on some SOLID rules, otherwise a change in those classes for some feature in project A can easily break your business logic in project B.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
When setting up a MVC project I like to have seperate projects in my Visual Studio Solution. One project handles the main things, like Controllers and Views, and then I have a separate project for the Data Layer and one project for Utilities. The Main project references both the other projects. The Data Layer references the Utilities project.
With this structure I am facing a problem, when I try to implement a utility method like this:
public static string GetCountryFromID(int id)
{
dev_Entities dbContext = new dev_Entities();
var country = from c in dbContext.countries
where c.id == id
select c;
return country.FirstOrDefault().country_name.Trim();
}
The method works with the Database, but my Utilities project can't reference the Data Layer project, because otherwise there would be a circular dependancy, which is forbidden by Visual Studio. So what is the best way to work on the Database and where should I put the belonging utility methods?
Edit:
I chose this example for a utility method, because it's an action I have to do often and I would like to avoid duplicate code.
Regarding structure of the project, It is important to have separation by means of different project, for example Business logic, data access, utilities and so on.
This helps in achieving separation of concerns. But this is just one first step towards separation of concerns. To further strengthen it, use of interfaces is encouraged so that one implementation can be swapped easily with other type of implementation.
Regarding the issue of circular dependency, the method put up in Utility is not exactly a utility method, it is more of a data access method. I feel access to DBcontext should be done in a controlled manner from data layer project only.
What I usually do is on how I "architecture" my projects:
API/MVC with reference only to my DAL Services and DTOs
Then in my DAL, I split it up into two, Commands and Queries, with each action/query/update/create on each own class file. Also I either I add their my DTOs or on a different project. And they only references my Utilities/Services (String transformation, enum to string, etc.)
In your case, I would not call your GetCountryById as Utility or Service as it access database and only returns string. I would put it in my DAL>Queries as it access the database and only return a specifc part of it.
First Question: Is this a recommended structure?
Yes.
Second Question: With this structure I am facing a problem...
From your limited code example, I can't see where the conflict is. But, your Data Access project should have one job, and one job only: Talk to the database.
Your Data Access project SHOULD NOT NEED to know anything about your Utilities project. There should be nothing in the Utilities project that is needed by the Data Access project to talk to the database.
Also, you should not call the Data Access project from within the Utilities project either. The two should really not even know that the other exists.
A common structure should look like this, in a simple web-based app:
[UI]
|
[Business Logic]
| |
[Utility] [DataAccess]
Where each | represents a reference.
The method in your example, GetCountryFromID should be in the DataAccess project.
EDIT:
I should also add: It looks like you are using Entity Framework (EF). Your Data Access project should be the only project that has the EF .dll's in it. None of the other projects should know anything about EF. Among other advantages, if you ever want to swap out your data access tools (say to something like Dapper) then this change would only impact a single project.
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.
just finished one of my projects and about to start another. This is never taught in my university so i dont even know if it exists. Lets say for example you have the code...
MessageBox.Show("Hi");
Now i know i can call it in Form1.
I also know i can call it in another form providing it is in a public class / void or something?
My question is, is there a library system where i can add 30-40 code snippits each to do their own job. So when i want to update sql or run calculations i just call a code file from a library?
Sorry if im missing something obvious google is driving me insane, i know what i want to ask, just not how to ask it! Hope you understand my question..
Thanks, Regards..
Of course. In your solution in Visual Studio you can add a Class Library project and fill it with all of the re-usable code that you want. Then any project in the solution can reference it by adding a Project Reference to that project.
Note that it's very easy to go overboard on something like this. Take, for example, your example:
MessageBox.Show("Hi");
The MessageBox class is tightly coupled to the user interface. So it belongs in the user interface objects. (The forms in this case.) This is because if you try to use it in your class library then you would need to add user interface libraries to that class library, making it more tightly coupled with that specific user interface implementation. This makes the class library much less portable and less re-usable because it can only be used by projects of that same user interface technology. (Can't be used by web projects, for example.)
So you'll want to think about each common utility that you encapsulate into its own re-usable code. Does it belong in the UI, in the business objects, in the data access, etc.? If it's tightly coupled with a specific periphery technology (user interface technology, data access technology, etc.) then it probably belongs there.
One approach to this would be to have multiple "common utilities" libraries. Using a contrived naming scheme, a larger enterprise domain solution might have projects like this:
Domain.BusinessLogic (class library, referenced by everything)
Application.Forms.AdminPanel (forms application)
Application.Forms.OperationsPanel (forms application)
Application.Forms.Common (class library, referenced by other Forms apps)
Application.Web.PublicWebsite (web application)
Application.Web.Common (class library, referenced by other Web apps)
Infrastructure.DataAccess.SQLServer (class library, dependency-injected into the Domain)
Infrastructure.Vendor.SomeService (class library, dependency-injected into the Domain)
etc.
So you have a core business logic project, which contains anything that's universal to the entire business domain in which you're working. It should have no dependencies. (Not rely on user interfaces, databases, frameworks, etc.) Then you have applications of various technologies, into which are mixed class libraries which have application-coupled common functionality. And finally you have the other periphery of the domain, the back-end dependencies. These could be your data access layer, integrations into 3rd party systems and services, etc.
As any given piece of functionality is abstracted into a common utility to reduce duplication and increase re-use, take care to keep your code-coupling low so the "common utilities" aren't tightly bound to "uncommon dependencies." All too often in the industry there's an increase in tight coupling with code re-use. (See the Single Responsibility Principle.) So exercise good judgement to avoid that.
There's nothing inherently wrong with writing the same piece of code ("same" by keystrokes alone, not necessarily by conceptual purpose) more than once if it serves more than one responsibility and those responsibilities should not be mixed.
It sounds like you want to use static methods. Group your routines by what they do, and put them in a static class, .e.g
internal static class Utility
{
public static void Method1(int whatever)
{
// do stuff
}
public static void Method2(string another)
{
// do other stuff
}
}
You can then call them like:
Utility.Method1(7);
Utility.Method2("thingy");
The simple solution is create a new project and select the "Class Library" option. This will create a class which is compiled into a DLL (dynamically linked library). Everywhere you want to use this common code you add can add a reference to the assembly, then in the specific files you use it, you'll have to add a using statement for it.
If you're required to turn in multiple projects you could put all of them under a single solution. If you right click the solution and select the properties option for the drop down menu it will open a new window with a "Configuration Properties" option in the left nav bar. Select it, then you can specify build dependencies. So if you have projects A and B which use methods in project C (the class library) then you can set that as a build dependency meaning whenever you build project A, B or the solution as a whole, it will first build project C.
This is commonly how enterprise software is structured; some dll's or exe's that are the application level code, then many other projects which build common code that is often shared by multiple projects. All of this is usually put under the umbrella of a single solution.
If you go this route there are more details (like which exe runs by default when you debug) that I can update with. It's probably nothing you'll be taught in university but you'll most likely see as soon as you start your first job.
I wrote some classes that I use with many different projects.
For example, I use Library.Controls.FlatButton.cs almost in every project.
The problem is when I add this as an "existing item"; the class gets created/copied in my soultion folder everytime. And each time I edit/update the contents of that class, I have to update all the Library.Controls.FlatButton.cs files in every project folder.
I need to be able to edit a single source of FlatButton class and when I compile/build a project (that uses the class file) gets updated to the new version of that class.
Question 1: Is there a way to do this?
I know that I can gather all these classes in a library project (Library.Controls) and add it to each application solution as a dependency.
Question 2: Is this the only way to work from a single source of common library files? And if I do; will all the classes in the Library.Controls namespace get compiled with every application, even if I've only used this FlatButton class in the project?
Hope this is clear for you..
thanks
I'd rather go with the approach of the shared library and add them as references to your client project.
If you don't want to do this. You could add the file as "Link". In Add existing item, select Add as Link instead.
Yes, a class library is the way to go and yes, since the whole class library will be referenced from your applications, all the classes will be available to it.
However, the fact that all the classes are available is not a bad thing, since they're in a separate class library it won't make your applications harder to understand (since the amount of code in those applications will stay the same), it might just be that you use up a little bit more hard drive space, though if you really worry about that you could put the class library in the GAC so that all apps reference the same copy of the library, though you'd better research this first to make sure that it's suitable for you.
Alternative way is to add FlatButton.cs file "As Link":
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.