我正在将Symfony集成到一个旧的应用程序中,该应用程序有自己的基于PSR-11的依赖容器。一直在寻找将DI容器合并到Symfony使用的容器的解决方案,但未找到任何结果。为了让它发挥作用,我提出了一个我不喜欢的“黑客”解决方案。
我创建了这个类。它在其中创建一个旧DI容器的实例:
class OldAppServiceFactory
{
private ContainerInterface $container;
public function __construct()
{
$this->container = OldContainerFactory::create();
}
public function factory(string $className)
{
return $this->container->get($className);
}
}
并将正确的条目添加到services.yaml
:
oldapp.service_factory:
class: Next\Service\LeonContainer\LeonServiceFactory
OldApp\Repository\Repository1:
factory: ['@oldapp.service_factory', 'factory']
arguments:
- 'OldApp\Repository\Repository1'
OldApp\Repository\Repository2:
factory: ['@oldapp.service_factory', 'factory']
arguments:
- 'OldApp\Repository\Repository2'
OldApp\configuration\ConfigurationProviderInterface:
factory: ['@oldapp.service_factory', 'factory']
arguments:
- 'OldApp\configuration\ConfigurationProviderInterface'
有了上面的黑客,把这些类放在服务类构造函数中就可以了。不幸的是,它看起来很糟糕,用更多的存储库来扩展它会很痛苦(尤其是当有50个存储库时)。有没有可能在services.yaml
中实现这样的东西?
OldApp\Repository\:
factory: ['@oldapp.service_factory', 'factory']
arguments:
- << PASS FQCN HERE >>
这将使我在服务中只有一个条目。yaml
用于旧应用程序的单个命名空间。
但是,也许我的问题有其他解决办法?一直在尝试配置Kernel.php
和preareContainer(...)
方法,但我也没有结束,因为旧的依赖项在一个PHP文件中返回一个数组:
return array [
RepositoryMetadataCache::class => static fn () => RepositoryMetadataCache::createFromCacheFile(),
EntityCollection::class => autowire(EntityCollection::class),
'Model\Repository\*' => static function (ContainerInterface $container, RequestedEntry $entry) { ... }
];
您可能可以通过自定义编译器过程轻松完成此任务。
首先通过加载旧存储库类所在的目录来标记所有旧存储库类:
OldApp\Repository\:
resource: '../src/OldApp/Repository/*'
autowire: false
autoconfigure: false
tags: ['oldapp_repository']
(我认为您可能还需要从默认的自动服务加载中排除src/OldApp
。例如:
App\:
resource: '../src/*'
exclude: '../src/{OldApp/Repository,DependencyInjection,Entity,Tests,Kernel.php}'
... 但我不是100%确定,测试一下这个)。
然后创建一个编译器通道来遍历标记并为每个标记定义一个工厂:
class OldAppRepositoryCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
$taggedServices = $container->findTaggedServiceIds('oldapp_repository');
foreach ($taggedServices as $serviceId => $tags) {
$definition = $container->getDefinition($serviceId);
$definition
->setFactory([service('@oldapp.service_factory'), 'factory'])
->addArgument($serviceId);
}
}
}
在Application Kernelbuild()
方法中添加编译器传递:
// src/Kernel.php
namespace App;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
// ...
class Kernel extends BaseKernel
{
// ...
protected function build(ContainerBuilder $container): void
{
$container->addCompilerPass(new OldAppRepositoryCompilerPass());
}
}
现在还不能测试这个,但这应该会让你朝着正确的方向前进。有关更多详细信息,请查看文档:
问题内容: 我想将由Razor MVC帮助程序在我的登录表单中生成的RequestVerificationToken传递给我为管理应用程序身份验证而完成的AngularJS服务 我的形式如下: @ Html.AntiForgeryToken()以这种方式呈现: 我的AngujarJs控制器成功注入了我的“ loginService”,我可以通过Post发送用户名和密码到服务 服务: 我的问题是如何
问题内容: 我想将关联数组传递给json wcf服务。 因此,在JavaScript中,我与此类似: 在我的wcf服务中,我希望有一个字典: 但是它将地图作为[Object object]发送而不是序列化,因为’map’实际上只是我为其分配属性的对象。 有谁知道我可以正确地序列化它以使其由WCF服务反序列化为Dictionary对象? 问题答案: 默认情况下,WCF不表示为JSON对象- 而是将它
问题内容: 将“当前”传递给AngularJS服务是否正确? 我处于一种$ service的状态,知道它仅由一个控制器使用,并且我想在$ service方法本身中引用该控制器的作用域。 这在 哲学上是 正确的吗? 还是最好将事件广播到$ rootScope,然后让我的控制器侦听它们? 问题答案: 要让控制器知道何时发生异步,请使用Angular promises。 要触发,您不需要作用域,可以调用
问题内容: 因此,我阅读了android AIDL文档,并对RPC在活动和服务之间的工作方式有一个大致的了解。但是,对于我的应用程序来说,实现这些功能似乎有些麻烦:基本上,我想向Service传递一个不错的处理程序,以便其线程可以将数据传递给Activity。目前,我正在通过使用静态公共成员(黑客)来解决此问题,但我更希望仅在服务的启动Intent中传递Handler对象。例如,我可以在创建时轻松
这可能是一个简单的问题。我尝试过谷歌搜索,但没有成功。我有一个DTO,它是从客户机传递过来的,由restful Web服务使用。但是得到这个例外 这是我的restful方法。 这是我平静的呼唤
问题内容: 我正在尝试调用webservice方法并将参数传递给它。 这是我的网络服务方法: 这是我的目标C代码: 因此,当我致电GetHelloWorld时,它的效果很好,并且: 显示HelloWorld,但是如何调用GetHelloWorldWithParam?如何传递参数? 我尝试: 并将以下两行添加到请求中: 我有错误: 谢谢您的帮助!泰迪熊 问题答案: 我已经使用了您的代码并进行了一些修