Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC - How to pass data to service

I'm a bit confused on how to perform insert and update statements using MVC. Is it ok to create an instance of an object in your controller and pass it to your service to save it or do you pass data to your service and handle everything else in there?

Insert

In my controller something like:

$userservice->insert("myname","mypassword");

In my UserService:

function insert($username,$password){
      $user = ORM::for_table('user')->create();
      $user->username= $username;
      $user->password= $password;
      $user->save();
}

Update

In my controller something like:

$userservice->update("myname","mypassword",1);

In my UserService:

function insert($username,$password,$id){
      $user = ORM::for_table('user')->find($id);
      $user->username= $username;
      $user->password= $password;
      $user->save();
}

Is this good practice? Because I see a lot of these answers where for example a user is being created in the controller and passed to a repository to save it: Proper Repository Pattern Design in PHP? But I don't like the idea of creating a user in the controller...

like image 671
randomizer Avatar asked Jan 07 '14 14:01

randomizer


People also ask

How pass data from controller model in MVC?

The other way of passing the data from Controller to View can be by passing an object of the model class to the View. Erase the code of ViewData and pass the object of model class in return view. Import the binding object of model class at the top of Index View and access the properties by @Model.

How pass data from view to view in MVC?

ViewBag. ViewBag is a very well known way to pass the data from Controller to View & even View to View. ViewBag uses the dynamic feature that was added in C# 4.0. We can say ViewBag=ViewData + Dynamic wrapper around the ViewData dictionary.

How pass data from view to controller in MVC TempData?

TempData is used to transfer data from view to controller, controller to view, or from one action method to another action method of the same or a different controller. TempData stores the data temporarily and automatically removes it after retrieving a value. TempData is a property in the ControllerBase class.


2 Answers

Controllers belongs to application layer and controlls only activity. In your example the activities are Create- and Update for an existing or for a new User. These operations belongs to the Domain Layer, which contains services. Thus services encapsulate the domain as a gatekeeper and provides operations for resolving domain like a facade.

Is it ok to create an instance of an object in your controller and pass it to your service to save it or do you pass data to your service and handle everything else in there?

The service should provide a method to pass a ValueObject. ValueObjects are better to encapsulate lot of data (Property values for User). Inside the service, the ValueObject should be delegated to Filter and Validator. If validation didn't fail the ValueObject will be delegated to a DataMapper. The DataMapper will map the properties of ValueObject to a data-model for the UserRepository (ORM). Repositories often need another model of data, e.g. Objects versus storage mediums based on RDBMS like MySQL.

This approach should be strict to seperate the concerns between layers to improve maintainabilty and interchangeabilty. Services should be thin and acts as a delegator to Domain Objects (Filter, Validator, etc.), for example see Service Layer Pattern.

So, where should be a value object created?

I would prefer that the service provides a method for this: getEntityPrototype() by using the prototype pattern. Be careful with naming. ValueObject is an object which have no identity. Entity is an object with identity (here id of User). For an existing User you will have have a method like getUserById($id), which should return an UserEntity. If User does not exist for given id, it should return a NullObject. To create a new User getEntityPrototype() will return an UserEntity which have no identity yet, so you will call it ValueObject or better Prototype of Entity. After setting properties (e.g. by a FormObject) and persisting this object is a real entity. In a Factory for this service you can set the EntityPrototype.

like image 142
Mamuz Avatar answered Sep 28 '22 06:09

Mamuz


What you should think about in this case is if the classes have only one responsibility.

Controller decides about the flow of the action. If there's a need for registering a user then it registers him, but it should not define how to do it, but ask a service to complete this task and get the result.

On the other hand you should have some kind of UserManager which updates, creates and fetches users - is this single responsibility? Kinda, yes - it's managing them in a broad sense.

There's a slight problem you have with your methods' names though. You should have registerUser not insert since it's way easier to tell what it actually does.

like image 27
Uriziel Avatar answered Sep 28 '22 07:09

Uriziel