IoC容器不会在app/models中注入新的具体类来扩展composer包中的src/models


IoC container does not inject the new concrete class in app/models that extends src/models in composer package

我在我的包rowland/laravelblog中有一个雄辩的模型Post,它使用存储库模式。它有一些默认实现,但是我希望我的包的用户在他自己的应用程序中扩展这个模型Post。然而,由于我使用存储库模式,这是我的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());
        });
    }

我的问题是,当用户安装这个包并扩展我的Post模型时,如下所示

<?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');
    }
}

laravel IoC容器在我的包中解决Post模型,而不是在用户应用程序中解决Post模型,这提供了一个困难的困境,我认为存储库模式是一个非常错误的模式,因为它带来的问题比解决方案更多。

编辑我知道它在包中注入了Post模型,因为用户不能访问应用程序Post模型中的自定义方法,例如用户不能调用$post->categories()

是否有人知道一种方法来确保应用程序的Post模型是一个注入,而不是一个在包?

您的PostRepository不知道将要在使用它的包中创建的类。您显式地创建一个Entities'Post'Post类的对象并将其传递给存储库,这就是为什么要注入Entities'Post'Post

为了使它为您工作,您需要让其他包配置您的服务提供者。最简单的方法是将您想要使用的类的名称放在配置文件中,并在实例化存储库时从配置中获取要使用的类名称。

public function register() {
  $this->app->bind('Repositories'Post'IPostRepository', function($app) {
    $model = $this->app['config']['app.post_model'];
    return new PostRepository(new $model);
  });
}