Laravel 5软件包中依赖注入的最佳方法 [英] Best approach for Dependency Injection in Laravel 5 package

查看:93
本文介绍了Laravel 5软件包中依赖注入的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Laravel 5开发一个软件包,现在我需要从依赖注入中受益,以拥有一个更具扩展性和可靠性的应用程序,我不知道哪种方法最好,为什么,这是其中的一部分我的代码,我需要注入Lang类依赖项

I am developing a package for Laravel 5, and now I need to benefit from dependency injection to have a more scalable and relaible application, I don't know which approach is the best to take and why, this is a piece of my code and I need to injected the Lang class dependency

 class MyController extends \App\Http\Controllers\Controller
 {        
    public $text;
    public $lang;

    public function __construct()
    {         
       // Some codes here                            
    }

    public function myFunction(){
       $this->text = \Lang::get('package::all.text1');           
     }
}

在此链接中, http://laravel.com/docs/4.2/ioc 建议2种方法,Automatic Resolution根据我对链接的理解 采用第一种方法,我需要添加

In this link http://laravel.com/docs/4.2/ioc 2 approaches are suggested, Basic Usage and Automatic Resolution based on my understanding from the link taking the first approach I need to add

 App::bind('lang', function($app)
{
    return new \Lang();
 });    

到应用程序的注册部分,然后在函数中我将得到一些信息 像这样:

to the register part of application and then in the function I'll have something like this :

 public function myFunction()
{
  $lang = \App::make('lang');       
  $this->text = $lang::get('package::all.text1');           
 }

另一种方法是像

  public function __construct(Lang $lang)
  {         
      $this->lang = $lang;
  }

然后实例化类中的对象

  $myController = App::make('MyController');

考虑到此classController并且将在routes文件中调用,哪种方法是更好的选择,如果我对链接的理解不正确,请更正我.还请告诉我为什么您建议其中任何一种方法.

Which way is the better way to take for, considering that this class is a Controller and it will be called in the routes file, or please correct me if my understanding from the link is not right. please also inform me why you suggest any of those approaches.

推荐答案

应该注意的是,使用本地IoC分辨率($app->make() stylee)并不比直接使用立面(Lang::get() stylee)更好-仍然非常依赖Laravel的特定类,而没有真正使您的代码明确声明它需要这些确切的类.因此,一般的建议是,如果您希望代码尽可能地可移植,则应尽可能地对接口进行编码.

It should be noted that using local IoC resolution ($app->make() stylee) is not much better than using the facades directly (Lang::get() stylee) - you're still very much relying on Laravel's specific classes without really making your code explicitly state that it needs these exact classes. So the general advice is to, as much as possible, code to an interface if you want your code to be as portable as possible.

在PHP开发中,当然有很多不利之处:

Of course there are a couple of big downsides to this currently in PHP development:

  1. 这些接口通常没有定义(除了 PSR-3 LoggerInterface接口),因此您仍然必须依靠该接口的特定实例(在本例中为Laravel的实例).
  2. 如果您决定创建自己的通用接口(或者图最终创建了其中的一些接口),那么Laravel提供的用于翻译的类(例如)根本不会实现它,因此您需要将现有的接口子类化只是为了使其看起来像实现了您自己的界面.但是,嘿,这是当前的最佳实践,所以我想您是否想使用当前的最佳实践,对接口进行编码,并且暂时不必担心您要编码的接口是特定于Laravel的. /li>
  1. These interfaces are not generally defined (except the PSR-3 LoggerInterface interface) so you still have to rely on a particular instance of the interface (in this case, Laravel's).
  2. If you decide to make your own generic interface (or the FIG eventually creates some of these), the classes that Laravel provides for translation (for example) don't implement it anyway, so you then need to subclass the existing ones just to make it look like it implements your own interface. But hey, that's the current best practice, so I guess if you wanna be using the current best practices, code to an interface, and don't worry for the time being that the interface you're coding to is Laravel-specific.

但是无论如何,这是我对您的特定问题的看法.首先,我应该说我还没有真正使用过Laravel 5(只是4s),但是我总体上一直关注它的发展.

But anyway, here are my thoughts on your specific question. First off I should say that I haven't actually used Laravel 5 yet (just the 4s), but I have generally followed its development.

如果我正在编码的类将大量使用给定的依赖关系,或者作为类如何工作的核心部分,我将使用构造函数依赖关系注入.此处的示例是控制器中的Request或某个Repository类,或控制台命令类中的业务逻辑类.

If the class I am coding will use a given dependency quite a lot or as a core part of how the class works I will use constructor dependency injection. Examples here are the Request or some Repository class in a controller, or a business logic class in a console command class.

如果我只需要特定的用途(也许是从控制器重定向并需要生成URI),则可以从IoC容器($this->app->make())解析本地版本,然后使用它.如果我使用的是Laravel 5,而Laravel直接调用了该方法(例如,控制器的动作方法),我可以为此使用方法注入,则我不确定100%.

If what I need I only need for a specific purpose (maybe redirecting from a controller and needing to generate a URI) I will resolve a local version from the IoC container ($this->app->make()) and then use that. If I were using Laravel 5 and the method was called by Laravel directly (e.g. a controller's action method) I may use method injection for this, I'm not 100% sure.

最后一点,一般建议是,如果由于很多依赖性而使构造函数方法签名太大:

As a final note, the general advice is that if your constructor method signatures get too big due to a lot of dependencies:

  1. 现在该看看您的代码是否过于依赖外部依赖项.也许您的类的某些功能可以提取到其自己的类中,从而将两者之间的依赖关系分开.
  2. 您应该考虑使用setter方法而不是构造函数注入-因此,您可以使用$class->setRequest()方法来代替接受Request对象.这样做的缺点是您需要告诉Laravel的IoC容器如何实例化您的对象(即必须调用这些setter).没什么大不了的,但是值得注意.
  1. It's time to have a look at if your code relies too much on external dependencies. Maybe some of the functionality of your class can be extracted to its own class that splits the dependencies between the two.
  2. You should consider using setter methods rather than constructor injection - so instead of accepting a Request object, you have a $class->setRequest() method. The downside of doing this is that you need to tell Laravel's IoC container how to instantiate your object (i.e. that these setters must be called). It's not that big a deal but something worth noting.

相关链接:

  • Laravel 5's IoC article
  • Laravel 5's Controller injection advice

这篇关于Laravel 5软件包中依赖注入的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆