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.
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.
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 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 8 years ago.
Improve this question
I have a C# project that needs to refactor. Project uses WPF+MVVM Light toolkit. I found the MainViewModel(...) constructor that receives about 50 parameters (factories interfaces). I think not. Am I right? I'm interested, because I want to improve my OOP thinking. Thanks.
P.S. Sorry for my grammar. Check me if you find errors.
Clean Code: A Handbook of Agile Software Craftsmanship, page 40, states that...
The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification - and then shouldn't be used anyway.
Consider the book as guidelines for software design, and as such, recommendations when thinking about your code structure.
50 factory interfaces means your ViewModel is way too big and trying to do too many things at the same time. You should break it into separate ViewModels that will appear as properties on the main view model.
WPF allows composition and any framework that allows ViewModel first (ie anything except PRISM) will compose the corresponding views form the ViewModel it encounters. I'm not sure about MVVM Light but with Caliburn.Micro this is almost a non-issue.
If MVVM Light doesn't automate this, you'll have to bind the WPF controls that will contain a specific child model's view to the child model property on the main view model.
Another option is to bundle multiple factory interfaces into parameter objects and pass these to the constructor, bringing the number of parameters to 4-5 instead of 50. This is the Introduce Parameter Object refactoring. Some tools like ReSharper provide automation support for this refactoring.
If you combine this with a DI container the parameter objects can get initialized automagically simply by registering the individual interfaces.
The best solution though is to break the main model into submodels
You might look into using a Dependency Injector like Unity. Register all your Service, Factory, and associated Classes you need with the Unity Container and then you only need a single parameter for your ViewModel constructor which is the Unity Container.
50 parameters for a constructor seems insane to me...
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
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.