1

I have an eloquent model Post in my package rowland/laravelblog which uses the repository pattern . It has some default implementations , but I want the user of my package to extend this model Post in his own application. However, since am using repository pattern this is my PostServiceProvider

    <?php  

namespace Repositories\Post;

use Illuminate\Support\ServiceProvider;
use Repositories\Post\PostRepository;
use Entities\Post\Post;

/**
* Register our Repository with Laravel
*/
class PostServiceProvider extends ServiceProvider {

     public function register() {

        // Bind the returned class to the namespace 'Repository\Post\IPostRepository'
        $this->app->bind('Repositories\Post\IPostRepository', function($app)
        {
            return new PostRepository(new Post());
        });

    }

My problem is that when a user installs this package and extends my Post model like below

<?php

namespace Entities\Post;

class Post extends Entities\Post\Post {

    /**
     * Defines the belongsToMany relationship between Post and Category
     *
     * @return mixed
     */
    public function categories()
    {
        return $this->belongsToMany('Fbf\LaravelCategories\Category', 'category_post');
    }
}

The laravel IoC container resolves the Post Model in my package rather than the one in the users app, and this provides for a difficult predicament such that I think the repository pattern is a very wrong pattern, for it raises more problems than solutions .

EDIT I know it injects the Post model in package because user cannot access custom methods in the app Post model e.g user can't call $post->categories()

Would someone know of a way to ensure that the applications Post Model is the one injected and not the one in the package?

jedrzej.kurylo
  • 39,591
  • 9
  • 98
  • 107
Otieno Rowland
  • 2,182
  • 1
  • 26
  • 34

1 Answers1

1

Your PostRepository doesn't know about the classes that will be created in packages using it. You explicitly create an object of Entities\Post\Post class and pass it to the repository, that's why Entities\Post\Post is injected.

In order to make that work for you, you need to let the other packages configure the your service provider. The easiest way is to put the name of the class that you want to be used in the config file and take the class name to be used from config when instantiating the repository.

public function register() {
  $this->app->bind('Repositories\Post\IPostRepository', function($app) {
    $model = $this->app['config']['app.post_model'];
    return new PostRepository(new $model);
  });
}
jedrzej.kurylo
  • 39,591
  • 9
  • 98
  • 107