I have a simple service on PHP with this structure:
Controller
ChannelControllerAPI.php
Service
ChannelService.php
Model
Repository
ChannelRepositoryInterface.php
RedisChannelRepository.php // implements ChannelRepositoryInterface
SqlChannelRepository.php // implements ChannelRepositoryInterface
HybridChannelRepository.php // implements ChannelRepositoryInterface
AbstractChannel.php
BusinessChannel.php // extends AbstractChannel
UserChannel.php // extends AbstractChannel
And I use DI container to resolve dependencies.
API controller code:
class ChannelControllerApi extends Controller
{
private $channelService;
public function __construct(ChannelService $channelService)
{
$this->channelService = $channelService;
}
public function getChannelInfo()
{
$channelId = $ths->request->Post('channelId');
$channelType = $ths->request->Post('channelType');
$result = $channelService->getChannelInfo($channelId, $channelType);
// return API request
}
}
I get ChannelService
in Controller Api __construct with DI;
ChannelService code:
class ChannelService
{
private $channelRepository;
public function __construct(ChannelRepository $channelRepository)
{
$this->channelRepository = $channelRepository;
}
public function getChannelInfo(int $channelId, string $channelType)
{
return $channelRepository ->findRules($channelId, $channelType);
}
}
ChannelRepository
code for example SQLRepository
:
use channel/Models/AbstractChannel;
class SqlChannelRepository
{
/**
* Channel $model (ActiveRecord or DTO Model)
*/
private $model;
public function __construct(AbstractChannel $model)
{
$this->model= $model;
}
public function find(int $channelId, string $channelType) : Channel
{
return $this->model->where('id', $channelId)->where('type', $channelType)->getModel();
}
}
Abstract channel model class code:
abstract class Channel extends ActiveRecordModel
{
protected $tableName = 'channel_business';
protected $fildmap = [
'id',
'type',
// ...
];
}
BusinessChannel
model class code:
class Channel extends AbstractChannel;
{
protected $tableName = 'channel_business';
}
UserChannel
model class code:
class UserChannel extends AbstractChannel;
{
protected $tableName = 'channel_user';
}
I don't want to pass $channelId and $type to Service or to Repository.
How? and in which layer can I pass the right model object to SqlChannelRepository
?
Where should this logic be placed:
if ($requset->Post('type') == 'user') {
$model = new UserChannel();
// or setting in DI container: app()->container::set('UserChannel');
} elseif ($requset->Post('type') == 'business') {
$model = new BusinessChannel();
} elseif .... {
......
}
Please help, which pattern or architect solution (can I use to create right ChannelModel
by request ($_POST) params and pass it to my repository)?
Sorry for my poor English:)