我已经使用了Dice PHP DI容器很长一段时间,它在注入依赖项的简单性方面似乎是最好的.
来自骰子文档:
class A {
public $b;
public function __construct(B $b) {
$this->b = $b;
}
}
class B {
}
$dice = new \Dice\Dice;
$a = $dice->create('A');
var_dump($a->b); //B object
Run Code Online (Sandbox Code Playgroud)
但是,当您必须使用直接相互依赖的对象时,由于无限循环,finall结果是服务器错误.
例:
class A {
public $b;
public function __construct(B $b) {
$this->b = $b;
}
}
class B {
public $a;
public function __construct(A $a) {
$this->a = $a;
}
}
Run Code Online (Sandbox Code Playgroud)
Dice的作者说没有办法从A或B类构造一个对象.如:
作者说,这个限制涉及所有 DI容器!
存在一个问题,即Mark Seemann未正确配置名为Captive Dependency的DI 容器。例如,很明显,当“PerCall”依赖项被注入到“Singleton”依赖项中时。但是当“Transient”被注入到“Singleton”中时的场景呢?对我来说,为什么我不应该对某些场景(例如注册为瞬态注入到单例服务并永远存在于那里的计时器)执行特别操作的原因并不是很明显。
SimpleInjector DI 容器中有Lifestyle Mismatches 诊断警告。描述说:
瞬态组件依赖于单例是安全的,但反过来不行
为什么不好?在这种情况下,坏事的好例子将非常有用。当它“总是”糟糕或可以允许某些场景时是否有任何限制(参见我上面的示例)?
我正在 Symfony 组件之上创建一个框架。 http://symfony.com/doc/2.7/create_framework/index.html
我想访问控制器中的容器,但我不确定如何以 OOP 方式进行操作。
我目前正在通过它访问它,global但我相信会有更好的方法来做同样的事情。请参考我的代码块:
#services.yml file
services:
calendar.model.leapyear:
class: Calendar\Model\LeapYear
Run Code Online (Sandbox Code Playgroud)
前端控制器文件
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing;
use Symfony\Component\HttpKernel;
$request = Request::createFromGlobals();
$routes = include __DIR__ . '/../src/routes.php';
$container = include __DIR__ . '/../src/app/Container.php';
$context = new Routing\RequestContext();
$matcher = new Routing\Matcher\UrlMatcher($routes, $context);
$controllerResolver = new HttpKernel\Controller\ControllerResolver();
$argumentResolver = new HttpKernel\Controller\ArgumentResolver();
$framework = new Framework($matcher, $controllerResolver, $argumentResolver);
$response = $framework->handle($request);
$response->send();
Run Code Online (Sandbox Code Playgroud)
闰年控制器文件
<?php
namespace Calendar\Controller;
use Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class LeapYearController …Run Code Online (Sandbox Code Playgroud) 我有一个控制台 .NET 核心应用程序,它使用该Microsoft.Extensions.DependencyInjection库作为依赖项注入框架。
我想使用这个框架来注入一个“向下”两个级别的依赖项,而不必在中间层多余地提及这个依赖项。我该怎么做呢?
目前,我注入依赖项的唯一方法是将其向下传递,直到需要为止。这是我的独立控制台应用程序,它演示了该要求。它是一个简单的程序,可以根据示例资产和负债金额计算一个人的净资产。(它实际上只是减去两个金额)。
该Program.cs文件包含程序主入口点并注册依赖项。
程序.cs:
public class Program
{
private static IServiceProvider _serviceProvider;
public static void Main(string[] args)
{
RegisterServices();
IServiceScope scope = _serviceProvider.CreateScope();
scope.ServiceProvider.GetRequiredService<ConsoleApplication>().Run();
DisposeServices();
}
private static void RegisterServices()
{
var services = new ServiceCollection();
services.AddSingleton<ICalculator, Calculator>();
services.AddSingleton<ConsoleApplication>();
_serviceProvider = services.BuildServiceProvider(true);
}
private static void DisposeServices()
{
if (_serviceProvider == null)
{
return;
}
if (_serviceProvider is IDisposable)
{
((IDisposable)_serviceProvider).Dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
设置依赖项注入后,Program.cs运行该ConsoleApplication.cs Run方法。
ConsoleApplication.cs:
internal class …Run Code Online (Sandbox Code Playgroud) c# design-patterns dependency-injection di-containers .net-core