- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一个小框架,我是这样编码的。我不确定它是否称为依赖注入(inject)。我不知道它是否像设计模式。我也不知道并想知道将 $this
作为参数传递是否是一种不好的做法。
看看这个; (不是一个工作示例,只是将这些代码写入浏览器以进行解释。)
/* This is engine model */
require_once('Database.class.php');
require_once('Image.class.php');
require_once('Misc.class.php');
require_once('BBCode.class.php');
class FrameWork_Engine_Model
{
public $database, $config, $misc, $bbcode, $controller, $image;
function __construct($config)
{
$this->database = new Database($configParams);
$this->image = new Image($this);
$this->misc = new Misc($this);
$this->bbcode = new BBCode($this);
$this->controller = new Controller($this); //here I call Register controller depending on routing, in this case, register controller.
}
...
}
/* This is register controller */
class Register extends Base_Controller
{
/*I can access anything over Engine Model in my controllers */
$this->engine->database->query(); //I access database model
$this->engine->bbcode->tag('you'); //I access bbcode model
$this->engine->image->sanitizeUploadedFile(); //I access image model
//etc. I can access others models like this.
}
基本上,我的 Controller 可以通过引擎模型访问任何模型。我相信 依赖注入(inject)就是将依赖注入(inject) Controller ?
比如,我的注册 Controller 需要数据库模型、路由模型和模板模型才能工作。这里有它所依赖的一切。我错了吗?
综上所述,我的问题是:
它是一个有效的依赖注入(inject)示例吗?如果不是,它是什么?它在设计模式中有名称吗?
如果与依赖注入(inject)无关,需要做哪些改动才能成为DI?
在新创建的类上传递 $this
参数是一种不好的做法吗?如果是,为什么?
附言。我知道在一个主题中问 3 个问题不是 stackoverflow 喜欢的,但我不想复制粘贴整个文本来问他们。
最佳答案
你快到了。
不,我不认为它是一个有效的依赖注入(inject)示例。它有点类似于服务定位器(因为您将整个容器注入(inject)到您的服务中并使用它来“定位”依赖的服务)。
您在依赖注入(inject)和依赖注入(inject)容器之间造成了一点混淆。
首先,依赖注入(inject)意味着在运行时将依赖项推送到对象中,而不是创建/拉取它们。
举个例子:
//hardcoded dependecies
class BadService
{
public function __construct()
{
$this->dep1 = new ConcreteObject1();
$this->dep2 = new ConcreteObject2();
}
}
所以在上面的例子中,BadService
使得无法在运行时连接其他依赖项,因为它们已经被硬拉到构造函数本身中。
//service locator pattern
class AlmostGoodService
{
public function __construct(Container $container)
{
$this->dep1 = $container->getADep1();
$this->dep2 = $container->getADep2();
}
}
在AlmostGoodService
例如,我们已经从前面的示例中删除了硬依赖性,但我们仍然依赖于我们容器的特定实现(这意味着如果不提供该容器的实现,我们的服务将不可重用)。这是与您正在做的事情相匹配的示例。
//dependecy injection
class GoodService
{
public function __construct($dep1, OptionalInterface $dep2)
{
$this->dep1 = $dep1;
$this->dep2 = $dep2;
}
}
GoodService
服务不关心它的具体依赖项的创建,并且可以在运行时轻松地与实现 $dep1
的“协议(protocol)”的任何依赖项“连接”。或 $dep2
的 OptionalInterface (因此得名 Inversion of Control - 依赖注入(inject)背后的基本概念)。
执行此接线的组件称为 dependency injection container .
现在,一个 dependency injection container ,在最简单的形式中,只不过是一个能够在运行时基于某种形式的配置连接你的对象的对象。
我说过你快到了,但是你的实现有一些问题:
$this
) 作为依赖项传递,因为那样你会回退到较弱的 inversion of control ,即 service locator .您应该将具体依赖项传递给您的服务构造函数在某些情况下,您会发现自己想要通过整个 $container
作为对服务(即 Controller 或惰性服务工厂)的依赖,但通常最好远离这种做法,因为它会使您的服务更可重用且更易于测试。当您觉得您的服务有太多依赖项时,这是一个好兆头,表明您的服务做了太多事情,现在是拆分它的好时机。
因此,根据我上面的回答,这是一个修改后的(远非完美的)实现:
/* This is the revised engine model */
class FrameWork_Engine_Model
{
function __construct($config)
{
$this->config = $cofig;
}
public function database()
{
require_once('Database.class.php');
return new Database($this->config['configParams']);
}
public function bbcode()
{
require_once('BBCode.class.php');
return new BBCode($this->database());
}
public function image()
{
require_once('Image.class.php');
$this->image = new Image($this->config['extensionName']);
}
....
public function register_controller($shared = true)
{
if ($shared && $this->register_controller) {
return $this->register_controller;
}
return $this->register_controller = new Register_Controller($this->database(), $thus->image(), $this->bbcode());
}
}
现在,要使用您的服务:
$container = new FrameWork_Engine_Model();
$container->register_controller()->doSomeAction()
有什么可以改进的?您的容器应该:
所有这些都附有关于 Dependency Injection 的清晰文档
关于php - 它是依赖注入(inject)吗?这是一种不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15323882/
我正在尝试测试依赖于其他服务 authService 的服务 documentViewer angular .module('someModule') .service('docu
如果我的网站上线(不要认为它会,目前它只是一个学习练习)。 我一直在使用 mysql_real_escape_string();来自 POST、SERVER 和 GET 的数据。另外,我一直在使用 i
我有以下代码,它容易受到 SQL 注入(inject)的攻击(我认为?): $IDquery = mysqli_query($connection, "SELECT `ID` FROM users W
我一直在自学如何创建扩展,以期将它们用于 CSS 注入(inject)(以及最终以 CSS 为载体的 SVG 注入(inject),但那是以后的问题)。 这是我当前的代码: list .json {
这个简单的代码应该通过 Java Spring 实现一个简单的工厂。然而结果是空指针,因为 Human 对象没有被注入(inject)对象(所以它保持空)。 我做错了什么? 谢谢 配置 @Config
我正在编写一个 ASP.NET MVC4 应用程序,它最终会动态构建一个 SQL SELECT 语句,以便稍后存储和执行。动态 SQL 的结构由用户配置以用户友好的方式确定,具有标准复选框、下拉列表和
首先让我说我是我为确保 SQL 注入(inject)攻击失败而采取的措施的知己。所有 SQL 查询值都是通过事件记录准备语句完成的,所有运算符(如果不是硬编码)都是通过数字白名单系统完成的。这意味着如
这是 SQL 映射声称可注入(inject)的负载: user=-5305' UNION ALL SELECT NULL,CONCAT(0x716b6b7071,0x4f5577454f76734
我正在使用 Kotlin 和 Android 架构组件(ViewModel、LiveData)构建一个新的 Android 应用程序的架构,并且我还使用 Koin 作为我的依赖注入(inject)提供
假设 RequestScope 处于 Activity 状态(使用 cdi-unit 的 @InRequestScope) 给定 package at.joma.stackoverflow.cdi;
我有一个搜索表单,可以在不同的提供商中搜索。 我从拥有一个基本 Controller 开始 public SearchController : Controller { protected r
SQLite 注入 如果您的站点允许用户通过网页输入,并将输入内容插入到 SQLite 数据库中,这个时候您就面临着一个被称为 SQL 注入的安全问题。本章节将向您讲解如何防止这种情况的发生,确保脚
我可以从什么 dll 中获得 Intercept 的扩展?我从 http://github.com/danielmarbach/ninject.extensions.interception 添加了
使用 NInject 解析具有多个构造函数的类似乎不起作用。 public class Class1 : IClass { public Class1(int param) {...} public
我有一个 MetaManager 类: @Injectable() export class MetaManager{ constructor(private handlers:Handler
我是 Angular 的新手,我不太清楚依赖注入(inject)是如何工作的。我的问题是我有依赖于服务 B 的服务 A,但是当我将服务 A 注入(inject)我的测试服务 B 时,服务 B 变得未定
我正在为我的项目使用 android 应用程序启动、刀柄和空间。我在尝试排队工作时遇到错误: com.test E/WM-WorkerFactory: Could not instantiate co
我不确定这是什么糖语法,但让我向您展示问题所在。 def factors num (1..num).select {|n| num % n == 0} end def mutual_factors
简单的问题,我已经看过这个了:Managing imports in Scalaz7 ,但我不知道如何最小化注入(inject) right和 left方法到我的对象中以构造 \/ 的实例. 我确实尝
在我的 Aurelia SPA 中,我有一些我想在不同模块中使用的功能。它依赖于调用时给出的参数和单例的参数。有没有办法创建一个导出函数,我可以将我的 Auth 单例注入(inject)其中,而不必在
我是一名优秀的程序员,十分优秀!