Multilayer architecture - explanation?
tl;dr: Have been mostly working on existing projects and have some problems in early stages of the architecture development.
Hey all!
I would need some additional explanation on how do you usually approach the multilayer architecture. I came across one early project which already had some of the projects made, but idk why and what should even be there (lets call this project
ExplainMe
.
So I have 4 "project" inside: ExplainMe
(controllers), ExplainMe.Core
(currently empty), ExplainMe.Data
(entities), ExplainMe.EF
dbContext..
Lets say I would like to implement an API request url/api/user?name=john
- Create UserController
inside ExplainMe.Controllers
.
- Create UserService
inside ExplainMe.Core.Services
(i assume?).
- what now? Which class am I missing and where? somewhere should probably be IUserService
, but where?7 Replies
- yes
- yes
- Yeah you would use an interface to make testing easier. This would be defined in either the Core project near the service most likely.
are IUserService and UserService both in Core project?
how would GetUserByName method look like? Should it get data from EF project or Data? Is Data only entities/models or is there any processing, etc?
Yeah, both in core. The interface only serves the purpose of allowing mocking in tests really.
Your service would probably have a DbContext be injected, or have a wrapper in the form of a repository. Its generally recommended NOT to use repositories over EF for various reasons thou, but its still pretty common in especially n-layer apps
If you have both an
EF
and a Data
project, data probably only contains the entities. I'd usually call that Domain
myself
the EF
project contains the context, the configurations and migrations, I assumethats right
yeah i always have some doubts about naming properly, lol
Aha, ok. so User service would have something like this:
private DbContext _myDbContext
Yup
But async etc ;p
yeye ofc 🙂
i previously watched some tutories/guides which connected Controller - Service - repository - context, and I just could figure it out why would you pass the stuff so many times
anyway thanks for your help 🙂
So the answer to that is... Complicated
You could obviously do the query directly in the controller
But now your controller is aware of your database, mixing data with http
Since introduce. Level of abstraction, the service. This lets us separate the work from the http stuff
Ok but what if we want to change database? Now we have to rewrite all our services, that might or might not use the datavase
So we move all dB access to its own thing, the repository
But the repository itself can't communicate with the database, that's what the context does. So we implement the repo using the context.
That's the reason. Is it s good reason? Many would disagree
Look at things like FastEndpoints, or Immediate handlers/ImmediateApi