控制反转 (IoC) 容器是一种管理类依赖的工具。依赖注入是一种消除硬编码类依赖的方法。相反,依赖项在运行时注入,从而实现更大的灵活性,因为可以轻松地交换依赖项实现。
IoC 容器解析依赖有两种方式:通过闭包回调或自动解析。 首先,我们将探讨闭包回调。 首先,一个“类型”可以被绑定到容器中。
App::bind('foo', function($app) {
return new FooBar;
});$value = App::make('foo');当调用 App::make 方法时,Closure 回调被执行并返回结果。
有时你可能希望将某些内容绑定到容器中,该内容应该只解析一次,并且在后续对容器的调用中应该返回相同的实例:
App::singleton('foo', function() {
return new FooBar;
});您还可以使用 instance 方法将现有对象实例绑定到容器中:
$foo = new Foo;
App::instance('foo', $foo);在某些情况下,一个类可能依赖于一个接口实现,而不是一个“具体类型”。当出现这种情况时,必须使用 App::bind 方法来通知容器应该注入哪个接口实现:
App::bind('UserRepositoryInterface', 'DbUserRepository');现在我们来看以下代码
$users = App::make('UserRepositoryInterface');既然我们已经将 UserRepositoryInterface 绑定到一个具体类型,那么 DbUserRepository 将在它被创建时自动注入到此控制器中。
IoC 绑定,类似 事件处理程序,通常属于“引导代码”的范畴。换句话说,它们准备你的应用程序以实际处理请求,并且通常需要在实际调用路由或控制器之前执行。最常见的位置是 插件注册文件 的 boot 方法。另外,插件可以在插件目录中提供一个名为 init.php 的文件,你可以用它来放置 IoC 注册逻辑。
服务提供者是创建库并在一个位置执行分组相关的 IoC 注册的绝佳方式。在服务提供者中,你可能会注册一个自定义身份验证驱动、将你的应用程序的仓库类注册到 IoC 容器,甚至设置一个自定义的 Artisan 命令。
事实上, 插件注册文件继承了服务提供者并且大多数核心组件都包含服务提供者。 您的应用程序所有已注册的服务提供者都列在 config/app.php 配置文件的 providers 数组中。
要创建一个服务提供者,只需扩展 October\Rain\Support\ServiceProvider 类并定义一个 register 方法:
use October\Rain\Support\ServiceProvider;
class FooServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('foo', function() {
return new Foo;
});
}
}请注意,在 register 方法中,应用程序的 IoC 容器可通过 $this->app 属性供您使用。一旦您创建了一个服务提供者并准备好将其注册到您的应用程序中,只需将其添加到您的 app 配置文件中的 providers 数组即可。
你也可以在运行时使用 App::register 方法注册服务提供者。
App::register('FooServiceProvider');你可以使用 before 和 after 方法在请求路由之前注册特殊事件。
App::before(function ($request) {
// Code to execute before the request is routed
});
App::after(function ($request) {
// Code to execute after the request is routed
});服务容器每次解析一个对象时,都会触发一个事件。 你可以使用 resolving 方法监听这个事件。
App::resolving(function ($object, $app) {
// Called when container resolves object of any type...
});
App::resolving('foo', function ($fooBar, $app) {
// Called when container resolves objects using hint "foo"...
});
App::resolving('Acme\Blog\Classes\FooBar', function ($fooBar, $app) {
// Called when container resolves objects of type "FooBar"...
});如你所见,待解析的对象将被传递给回调函数,允许你在该对象被交给其消费者之前,在其上设置任何附加属性。
您可以使用 environment 方法来发现应用程序环境,该环境由 环境配置 决定。
// production
App::environment();可以使用 runningInBackend 方法来判断当前请求是否正在管理后台区域中执行。
App::runningInBackend();您也可以使用 runningInConsole 方法来检查正在执行的代码是否在 命令行界面 中运行:
App::runningInConsole();