In what scenario should we use a service container instead of calling a new class directly? I read from Laravel official docs that it is mainly used for managing class dependency and performing dependency injection, however I am not sure if I understand it correctly.
For example payroll applications, we would have a Payroll class, Employee Class, Leave Class, Timesheet Class. So to process a monthly payroll, Payroll class would depends on
- Employee Class (getBasicSalary)
- Leave Class (getUnpaidLeaveCount)
- Timesheet Class (getLateHoursCount)
Below is what I normally writes (without any design pattern)
Class PayrollProcessController
{
public function index(){
$payrollObj = new Payroll();
$payroll->setPayrollMonth('202106');
$payroll->process();
}
}
Class Payroll
{
private $payrollMonth;
public function process()
{
// loop employee from database
foreach ($employees as $employee_id){
$salary = $this->calculateNetSalary($employee_id);
// save into db
}
}
public function calculateNetSalary($employee_id)
{
$employee = Employee::find($employee_id);
$basicSalary = $employee->getBasicSalary();
$basicSalaryPerDay = $basicSalary / date('t');
$basicSalaryPerHour = $basicSalaryPerDay / 8;
$leaveTakenDay = Leave::getUnpaidLeaveCount( $employee->getId(), $this->payrollMonth);
$leaveDeductionAmount = $basicSalaryPerDay * $leaveTakenDay;
$timesheetLateHours = Timesheet::getLateHoursCount($employee->getId(), $this->payrollMonth);
$lateDeductionAmount = $basicSalaryPerHour * $timesheetLateHours;
$netSalary = $basicSalary - $leaveDeductionAmount - $lateDeductionAmount;
return $netSalary;
}
}
If apply with service container concept,
Class PayrollProcessController
{
public function index(Payroll $payroll){
$payroll->setPayrollMonth('202106');
$payroll->process();
}
}
Class Payroll
{
public function process()
{
// loop employee from database
foreach ($employees as $employee_id){
$employee = app(Employee::class);
$employee = $employee->find($employee_id);
$leave = app(Leave::class);
$timesheet = app(Timesheet::class);
$salary = $this->calculateNetSalary($employee, $leave, $timesheet);
// save into db
}
}
public function calculateNetSalary(Employee $employee, Leave $leave, Timesheet $timesheet)
{
$basicSalary = $employee->getBasicSalary();
$basicSalaryPerDay = $basicSalary / date('t');
$basicSalaryPerHour = $basicSalaryPerDay / 8;
$leaveTakenDay = $leave->getUnpaidLeaveCount( $employee->getId(), $this->payrollMonth);
$leaveDeductionAmount = $basicSalaryPerDay * $leaveTakenDay;
$timesheetLateHours = $timesheet->getLateHoursCount($employee->getId(), $this->payrollMonth);
$lateDeductionAmount = $basicSalaryPerHour * $timesheetLateHours;
$netSalary = $basicSalary - $leaveDeductionAmount - $lateDeductionAmount;
return $netSalary;
}
}
Questions:
-
Is the above concept correct?
-
I checked again on the service container documentation https://laravel.com/docs/8.x/container#when-to-use-the-container, it is written:
First, if you write a class that implements an interface and you wish to type-hint that interface on a route or class constructor, you must tell the container how to resolve that interface. Secondly, if you are writing a Laravel package that you plan to share with other Laravel developers, you may need to bind your package's services into the container.
So can I say that unless we are publishing the payroll modules as a laravel package for others to use or to write unit testing, there is no point in using a service container?
-
If we look at opencart's registry class, is that is similar to Laravel's service container? https://github.com/opencart/opencart/blob/e22ddfb060752cd8134abbfb104202172ab45c86/upload/system/framework.php#L9
-
Take an example from opencart, so Language class is singleton design pattern, while registry is container design pattern?
$language = new \Opencart\System\Library\Language($config->get('language_code')); $language->addPath(DIR_LANGUAGE); $language->load($config->get('language_code')); $registry->set('language', $language);
Aucun commentaire:
Enregistrer un commentaire