Just to learn about patterns I'm creating my Web API with these projects:
Entities, Repositories, Service and the API application.
Each controller in APIs use dependency injection to his corresponding service; each service use DI to multiple repositories; Repositories are used to get data from the DbContext and Entities contains DbContext and the DbSets.
As example let's say that when I call the /teams/1 endpoint:
the GetTeam(id) function in controller call _teamService.GetTeam(id);
the service call _teamRepository.GetTeam(id);
the repository does a LINQ call to Context.Team.First(...) a give back to the service the Team entity model;
the service get the model and map it to a DTO that go back to the controller;
the controller give it to the application in JSON format.
Is this a right way to manage the flow?
In addition, imagine that the controller must retrieve the team and all its competitions: is it right to inject the CompetitionRepository and use it from the TeamService? Something like:
TeamService.cs
return new DTOObject {
team = _teamRepo.GetTeam(id),
competitions = _compRepo.GetCompsByTeam(id) <-- is a list
}
I prefer to return entities from my services and not DTOs. The reason is that sometimes the result of a service call is used to create an ASP.NET MVC View Model and sometimes a DTO to return as a JSON. Sometimes the requirements for these DTOs are different, the server side ViewModels can see things that should not be exposed to the client. You can make a DTO in your service layer but in most cases it is just another mapping that you have to take care of for not that much value. This is why I create DTOs or ViewModels directly from entities in the controller.
Also the repository pattern is mostly useless. It might be useful if you change your data store but in practice these kinds of changes come with a lot of other changes to the business logic so most of your service layer is rewritten anyway so the value is lost.
Related
I have a small ASP.NET API that exists in two separate projects. The API project holds my controller classes and request/response models. The Logic project holds business logic and database models.
If a user submits a request, lets say a BookRequest, to my endpoint, where is the best location to handle conversion to my Book database model? Originally I had planned to have the Book model take a BookRequest as a constructor, however that would create a cyclical dependency, as Logic would need to reference API. I could move the RequestModels into the Logic project, however I feel those should live in the API project as they are specific to the controllers. The alternative would then be to have the API convert to the database model and pass that to the logic.
Is there a better method for handling this case while keeping the projects seperate?
To avoid the cyclical dependency you described you may want to consider breaking things out into a third project, with its own models. The problem comes in because your 'Logic' project maintains both your business logic and database models.
A simple example would be:
API with API-Models <--> Business Logic with DTOs <--> DAL with DB Models / Entities
In this example the Business Logic layer would handle the translation of API Models to DTOs (Data Transfer Objects), and DTOs to values returned from the DAL (Data Access Layer).
Consider researching common architecture patterns to find one that may fit your needs. A common pattern I often use is the Clean Architecture.
Here is a link to Microsoft Architecture Patterns documentation:
https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures
Im doing a .NET solution and i have to architect this. So my architecture is like below.
DLL(data logic layer) (Where i have all my repositories to access data)
Models(In a schema wise)
ViewModels(Separately as class library )
Services Layer (Where manipulate data and sends to controller)
Here DLL will sent the data by accessing DB. Then Service layer will use these Repositories (etc. UserRepository) and manipulate the data as i want to send it to controller. In this case controller will return the ViewModels to views.
So what i wanna know is, when mapping data to ViewModels ,Should my service layer do mappings and return ViewModels to Controller ??
OR
Service Layer return as Models and in controller we do the mapping and create view models ?
What i feels is it is not good to have so many operations in the controller. So my service should return ViewModels ,So the controller have less work.
I would like to hear best practices and ideas ??
I would do mapping in the controller. Because there can be some instances we need to map the same service output to different view models. Otherwise, we have to write multiple service methods for each view model type.
You can simplify mapping by using AutoMapper.
Take a look at Where should I put automapper code? question.
It suggest using Automapper in service layer.
Also, configuring mappings is a static method, called only once, so it does not affect performance much: official getting started.
And for end, here is some more explanations for setup: SO answer
I am a newbie to .Net MVC and my question today is regarding the MVC pattern.
In our application we have a Service Layer which talks with the DB.
The Controller is Currently talking with the Service layer to get the values from the DB.
Our new Manager requires this service layer interaction from the Models and not from the Controller.
He does say that this architecture is to achieve a thin Controller. We are now starting to port the service layer interaction from controller to models.
And here comes my question. Apart from having a thin Controller, is there any other benefits from enforcing this pattern.
I would like to know the advantages and disadvantages of both pattern.
Some links would also be helpful
Why you shouldn't call services from your ViewModels:
ViewModels are supposed to be classes that contain some data that is interchanged between the View and the Controller. They should not perform any action or retrieve further data. They are dumb models, they don't do anything expect transport data.
What is a View Model
If you are having trouble understanding what a View Model is and what it isn't, think of it like a subset of your model. It only contains data that you need to display on a given view at a given time.
There are 3 types of Models - View Model, Domain Model and Data Model. Check here.
If you are talking about View Models then its a bad idea. There are ways to achieve a thin controller, but ViewModel never should interect with services. If its possible a Controller Action should only invoke a service and throw the result to View. Like this:
[HttpGet]
public ActionResult GetAnimals(int id)
{
var viewModel = new AnimalsService(id).GetViewModel();
return View(viewModel);
}
But in reality many times you can't do that for some obvious reasons. There are few things you can do though. Like don't validate models in controller, you can do that in service layer. Don't hesitate to create more services for different jobs, like pagination, context related logic or some third party api invocation. Create helper or utility classes for repititive codes. Also I think its ok to write fat services.
I have an application that is separated into 4 layers to keep code organized and be able to reuse it.
My layers are:
presentation layer: an mvc4 project
business layer: a c# library project whit the Business logic
Data layer: a c# library that contains all the linq to the db
model layer: a c# library that contains a edmx ef5 for my database
So the idea is that for each controller or our mvc project we have 1 business class and 1 data class. and if some functionality needs to make use of code on other class, they do at business logic layer (different business logic classes can create new instances of other business logic classes.)
The problem I was having is that I was creating too many DbContext and I was getting some errors and problems because of it. Like loosing the lazy loading on my BL layers or not been able to assign objects like list to other objects when they came from different DbContext.
For example, if I have a medic controller/logic/data and I use a patient logic/data to get a list of patient for today, I get an error when I try to do medic.patients = patienstList;
So what I need to do is use one DbContext per web request, so the DbContext will be created on the controller and injected to the logic layer and those will inject to other logic class or to the data classes?
How can I do it?
There are number of ways of doing IOC in MVC.
Example would Unity.. where you can register an instance of DBContext.
Of course if the lifetime of you IOC container every extends beyond web requests. your are in for nasty time.
Even if you think it is 1 Context per request that you need. Be very careful if you use ASP pipeline events and access DbContext, you may actually need 1 context per Thread. But if you are happy to say you access starts at MVC Controller level. Then you are looking for a way to handle inversion of control only.
Unity from microsoft
dependency injection docu
https://unity.codeplex.com/documentation
IMHO the Business Object should not have to use another Business Object because that violates the Single Responsibility Principle.
The Data Layer object should be able to do everything the Business Object needs it to.
So you should write methods in the Business Layer Object and Data Layer Object method GetPatientsForMedic.
You may say "but the Hospitals Business Object can get me a list of Hospitals really easily". That is not it's job, because you said it's job is to service the Hospitals controller.
HOWEVER the problem only happens when you pass a Hospital object from the HospitalsBO to the MedicBO. So don't.
On the Hospitals controller, write a method GetListOfHospitalIDsAndNames. Then, if you need a dropdown of hospitals, call that, and use the IDs and text names.
You can indeed share a DbContext between two Business Objects by sharing a Unit of Work. But you probably shouldn't.
However i'm no expert... i avoided these problems by having one GINORMOUS business object with everything in it. That is also a BAD THING.
Initial situation:
I would like to build an MVC3 application with a layered architecture. The layers would be the persistence
layer (repository pattern), service layer and the View layer. I also want to map entities to DTOs in the
persistence layer, and passing these DTOs to the View.
In the View I would like to apply the MVC pattern by using MVC3 weapp. Now my Question is, in which module, the Controller or the Model should i access (reference to) the service layer.
I always see references to the service layer in the controller, like this:
public class CustomerController
{
public ViewResult Details( int id )
{
CustomerDTO customerDto = MyService.GetCustomerById();
return View( customerDto );
}
}
Shouldn't I access the service layer in the Model module? If I access my service layer in the controllers, I don't need the Model module at all...?
I always work on the basis that any real work with the service layer is done in the controller.
If I access my service layer in the controllers, I don't need the Model module at all...?
Incorrect - it is highly unlikely that your service types either will have, or even should have the correct shape and metadata (for example [Display] or [DataType] attribution) or to make them work correctly with MVC views. You should have a Model type for all objects that get given to the view, even if they're one-for-one clones of your service types - because then you have a separation between the data that your view and controllers need and your service types.
If you try to bind your views directly to your service types, then you are creating either one of these two scenarios:
making it harder to change view & controller code because the data being sent to and fro has to conform to service types
making it harder to change service types because to do so would mean changing every view
The ViewModel (or Model, depending on your point of view) is your adapter between what's nice for viewing (displaying on a web page) and binding (receiving from a web page) - and it's simply the case that these two things will often drift apart from the actual service types used at the business logic level. Indeed they should, because they aim to solve different problems.
Depends on whether you want to hide MyService from controller.
In your example it's visible. If you had a method on Model of the same name that then delegated to MyService, it wouldn't be.
Advantage of hiding it is you could swap MyService for YourSevice without impacting the View and Controller layers.
As for no model. Where are you defining your DTOs then? Basically MyService would be your model.
You are also operating on the assumption that the DTO for model to controller to view is the same all the way through, even when adding at least one other layer.
I'd think through that assumption if I were you...