Öncelikle PostRepositoryInterface arayüzünü kurucu yöntem (__construct) içerisine tanımadıktan sonra store yöntemi içerisine enjekte etmeyeceksiniz. store yönteminde $this->post->create
şeklinde kullanacaksınız. Kurucu yönteme enjekte etmenin amacı zaten diğer yöntemlere enjekte etmeden her yerde kullanmak.
Diğer kısma gelince; diyelim ki $post->create yaptığınızda MySQL yanında aynı zamanda MongoDB'ye ve Elasticsearch'e kayıt işlemek istiyorsunuz, PostRepositoryInterface içerisindeki diğer yöntemleri de aynı şekilde diğerlerine uygulamanız gerekiyor. Yani bir stratejiye ihtiyacınız var.
interface AdapterInterface
{
public function create(Model $model);
// ...
}
class MongoDBAdapter implements AdapterInterface
{
public function create(Model $model)
{
// Elimizde oluşmuş bir Post objesi var. İçeriğine burada ulaşabilir
// ya da işlemler yaptırabiliriz. En basitinden $model->toArray()
// şeklinde içeriğini dizi olarak alabiliriz.
// ...
}
}
class ElasticsearchAdapter implements AdapterInterface
{
public function create(Model $model)
{
//...
}
}
interface AdapterLocatorInterface
{
public function setAdapter(AdapterInterface $adapter): Adapter;
public function getAdapters(): array;
public function hasAdapter(): bool;
}
class AdapterLocator implements AdapterLocatorInterface
{
protected $adapters = [];
public function setAdapter(AdapterInterface $adapter): Adapter
{
$this-adapters[] = $adapter;
return $this;
}
public function getAdapters(): array
{
return $this->adapters;
}
public function hasAdapter(): bool
{
return (bool)count($this->adapters);
}
}
interface PostStrategyInterface
{
public function create(Post $post): Post;
}
class PostStrategy implements PostStrategyInterface
{
protected $adapterLocator;
public function __construct(AdapterLocatorInterface $adapterLocator)
{
$this->adapterLocator = $adapterLocator;
}
public function create(array $attributes): Post
{
$post = Post::create($attributes);
if($this->adapterLocator->hasAdapter()) {
foreach($this->adapterLocator->getAdapters() as $adapter) {
$adapter->create($post);
}
}
return $post;
}
}
class PostRepository implements PostRepositoryInterface
{
protected $postStrategy;
public function __construct(PostStrategyInterface $postStrategy)
{
$this->postStrategy = $postStrategy;
}
public function create(array $attributes): Post
{
return $this->postStrategy->create($attributes);
}
}
$this->app->bind(AdapterLocatorInterface::class, AdapterLocator::class);
$this->app->bind(PostStrategy::class, function($app) {
$adapterLocator = resolve(AdapterLocatorInterface::class)
->setAdapter(new MongoDBAdapter)
->setAdapter(new ElasticsearchAdapter);
return new PostStrategy($adapterLocator);
});
$this->app->bind(PostStrategyInterface::class, PostStrategy::class);
$this->app->bind(PostRepository::class, function($app) {
$strategy = resolve(PostStrategyInterface::class);
return new PostRepository($strategy);
});
$this->app->bind(PostRepositoryInterface::class, PostRepository::class);
class PostController extends Controller
{
protected $postRepository;
public function __construct(PostRepositoryInterface $postRepository)
{
$this->postRepository = $postRepository;
}
public function store(StorePostRequest $request)
{
return $this->postRepository->create($request->validated());
}
}