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.
Related
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.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm learning about the different tiers in software development, such as the presentation tier, logic tier..etc.
So I have this RaceTrackSimulator project which is a Windows Forms Application. I want to separate all the classes (logic) from the GUI (presentation) and I did so like this:
But now the problem is, I don't know how to allow the classes to access and modify components of the GUI such as textboxes and labels. I think this is just a simple namespace issue, but that doesn't make sense because in each class it says:
namespace RaceTrackSimulator.BusinessLogic
How do I resolve such an issue?
Thanks!
You have just separated the business tier classes in separate folder which doesn't actually qualify as separate tier altogether. You should rather move all this classes in a separate project (example, class library project) and use the dll of that class library to your presentation tier form application.
You can as well choose, to write your business tier as WCF service and deploy them. In turn, your client/presentation layer will consume the service then to access business layer; which is one way good cause then for all different client's (UI or other) you don't have to ship the dll exclusively.
In your specific case, the problem could be that the namesspaces are different and in which case make sure, you are importing the correct namespace.
A few things it could be without looking at the actual code. The namespaces would be different from the 3 classes compared to your Form as they are in a different folder.
Also ensure that the components visibilty level is set to "Public" in the properties tab on the Form Designer. Once they are public, you should be able to access them in any of the 3 classes that you have created.
Did you put a
using RaceTrackSimulator.BusinessLogic;
At the top of the file where you are referencing your objects?
Where your code resides in terms of namespacing is irrelevant. You've done that fine. All you need to do is supply a means of accessing the components from your business logic classes. There's a multitude of ways of doing that depending on your requirements. You could supply a post(Object state) method in your form, and instantiate your logic class passing a reference to the form object. Your business logic can then simply post anything it likes back to the form and it's up to the form how it then handles the UI logic based on the data/message it receives from the logic layer. Or you could make your components more publicly visible to the logic layer. Or you provide an interface that allows access to the components directly.
Also, what you are calling Business Logic in your example above is not really logic. It's business model classes, by the looks of it.
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 9 years ago.
Improve this question
Abstract
Which name is better?
Domain.PersonService
DomainServices.PersonService
DomainServices.PersonDomainService (consider some longer names like PersonDomainServiceModelDecorator)
or something else?
Situation
We have a framework in which there are some base classes for each layer. Ex. Repository, Domain Services, UI, etc.
Each logical layer has a name which is used as its namespace:
"Data" for data layer that contains repositories; Ex. Fx.Data.DbContextRepository
"Services" for domain (not web) service layer; Ex. Fx.Services.CrudService
"Web.UI" for Web UI layer; Ex. Fx.Web.UI.Controllers.CrudController
We also follow the same rule for end-projects whith some extra layers:
"Data" Ex. Project.Data.PersonRepository
"Services" Ex. Project.Services.PersonService
"Web.UI" Ex. Project.Web.UI.Controllers.PersonController
"Entities" for code-first entities; Ex. Entities.Person
"Models" for object models; Ex. Models.Person.Criteria, Models.Person.PersonDeleteModel
My focus is on "Domain Service" layer but any ideas about other layers are also welcomed.
We've finally come to the conclusion that "Services" is not a suitable name for "Domain Services" as it may cause ambiguity between a "Web Service" or "Domain Service" layer.
Now we are changing the "Services" namespace to "Domain" or "DomainServices". But we have another problem. We put a "Service" suffix for every domain service class (Ex. PersonService). Now it seems ugly to have "DomainService" suffix (Ex. DomainServices.PersonDomainServer or DomainServices.DomainPersonService).
So it can be prettier to use "Domain" as namespace while class names show that they're services under domain namespace (Ex. Domain.PersonService).
I would go for two simple ideas:
try to define full names (namespace + type name) without
redundancy (the same name portion - Domain, Person, Service, Model,
Controller, ... - should not appear twice) whenever possible
get inspiration from the .NET framework itself. There are more than 40000 classes in there! Open all the
assemblies in a tool such as .NET Reflector or ILSpy and study
it carefully.
I would come up with something like this:
Domain
+ Person
+ PersonService // Domain service
Domain.Data
+ PersonRepository
Domain.ServiceModel // WCF, etc. I chose the same namespace as .NET Framework
+ PersonService // Service implementation, this is really a service so "service" redundancy seems unavoidable here
Domain.Web.UI
+ PersonController
Ok, it has the obvious inconvenient that the same type name appears multiple times in the hierarchy. Well, but that's why namespaces (and namespace aliases) exists also. I think it's not such a big deal.
Do you see any difference between Domain and DomainServices in your project? If you want to keep services and other domain entities in separate namespaces I believe you will need to move PersonService to DomainServices namespace.
Most of the time we do not look into namespace, we only mention classes that's why I think it is fine to have DomainServices namespace. At the same point of time if you have single domain across the application and do not have plan to separate it, I think it will be better to call it Domain.PersonService
Regarding the word 'Doman' in the class names, I really don't like this because it adds complexity to the name. You should try to build your application that way to be sure if you are opening PersonService you should be 100% sure it is domain service. You know that when you are opening PersonRepository, it is Data layer, the same for domain.
I would do this in either of these two ways:
1) Why not have subnamespaces for Services:
Services.Web for web servies
Services.Domain for domain servces
On another note, I would remove Web from Web.UI (provided that you do only have a web based UI).
2) If web services are actually living in the web layer they could be in Web.Services namespace in that case Web.UI is also acceptable. Domain Services would live simply in Services namespace.
My suggestion would be to put it as
<Company>.<Component>.<SubComponent>.<Module>.DLL**.
Microsoft recommends something similiar on this link http://msdn.microsoft.com/en-us/library/vstudio/ms229048(v=vs.100).aspx and an example will be **Microsoft.Practices.EnterpriseLibrary.Security.Dll
Hence, you might want to go with Company.Domain.PersonService
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'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.