grifart/nette-scoped-di

支持 Nette DI 的多个 DI 容器

v0.1.0 2021-01-04 16:26 UTC

This package is auto-updated.

Last update: 2024-09-16 23:41:06 UTC


README

将应用程序的依赖注入容器拆分为定义良好的范围,并强制执行它们之间的关系。

在单体和微服务之间

这种方法位于单体和微服务之间。

从架构角度来看,它与微服务方法等效。模型和应用程序之间存在明确的边界和接口。

技术上,你可以节省大量维护微服务所需的维护成本。因为仍然有一个应用程序,但它由许多独立的模块组成。它们有明确的边界和明确定义的依赖关系。当你打破这个边界时,你会得到一个异常。

所以如果需要,你可以轻松地将已经定义的模块转换为微服务。这里缺少的部分是一个序列化 & 网络堆栈。这可以通过在提取到微服务中的模块之间添加 RPC 层来轻松解决。

更多资源

示例

你有 一个模型,你想仅向少数外观公开访问。因此,您将它们从 模型 容器导出到 应用程序 容器,然后应用程序只能访问那些导出的服务。这意味着应用程序不能再忽略 ACL 规则或直接访问数据库。

将模型注册到用户 DI 容器中

对于模型容器,您必须创建一个 DI 扩展,以注册从 模型 导出到用户应用程序(UI/API/CLI/...)部分的全部服务。

<?php

declare(strict_types=1);

namespace App\Infrastructure;

use Mangoweb\NetteDIScope\ScopeExtension;
use Nette\Configurator;

final class ModelExtension extends ScopeExtension
{
	public static function getTagName(): string
	{
		// Every service marketed with an `exported` tag will be available in every *user* DI container
		return 'exported';
	}

	protected function createInnerConfigurator(): Configurator // @phpstan-ignore-line
	{
		$configurator = parent::createInnerConfigurator();
		$configurator->addConfig(__DIR__ . '/../container.neon'); // the configration entrypoint of the *model* container
		$configurator->addConfig(__DIR__ . '/../../config/config.local.neon'); // parameters that are needed for the *model* container
		$configurator->addStaticParameters([ // provide the %modelDir% parameter so the model is self-aware of where it lays
			'modelDir' => __DIR__ . '/../'
		]);
		return $configurator;
	}
}

用户 DI 容器中,注册此新创建的扩展

# the app-container.neon
# import public services from model-level container
# see Model/**/*.neon files for more info
extensions:
	model: Ivy\Infrastructure\ModelExtension

从模型容器导出服务

# model-container.neon
services:
	-
		factory: Ivy\Survey\SurveyFacade(
			# dependencies...
		)
		tags: [exported] # This makes it available for the outer container

要求模型容器的依赖项

当模型容器需要依赖项(EmailSender)时,它可以通过定义服务 torso 来要求它。

namespace App\Model\Infrastructure\Email;
interface EmailSender {
    function send(TheMessage $message): void;
}

然后告诉 DI,外层容器 必须 提供代码 EmailSender.

# model-container.neon

services:
	-
		type: App\Model\Infrastructure\Email\EmailSender
		factory: @outerContainer::getByType(Ivy\Infrastructure\Email\EmailSender)

外层容器随后注册该服务,您就完成了。

services:
    - MyEmailSender # implements App\Model\Infrastructure\Email\EmailSender

危险区域

有时,你需要打破与模型隔离的模式。请参阅 危险区域

贡献

此存储库是 mangoweb-backend/nette-di-scope 的分支。

主要开发地点是 gitlab.grifart.czmaster 会自动复制到 github:grifart/nette-di-scope

将贡献提交到分支

内部贡献

使用 GitLab 并打开合并请求,目标: master。合并后,它将自动传播到 GitHub。

外部贡献

外部开发者:使用 GitHub,针对 我们的 master 打开拉取请求。

拉取请求的内部审阅者和维护者

  • 获取本地存储库的更改
  • 然后将它们合并到本地的 master 分支
  • 将本地的 master 分支推送到 gitlab/master (这将自动传播到 GitHub)
  • 删除不再需要的分支

推荐的 git 远程仓库设置

git remote add origin https://gitlab.grifart.cz/grifart/nette-di-scope.git
git remote add github-grifart https://github.com/grifart/nette-di-scope.git
git remote add github-mangoweb https://github.com/mangoweb-backend/nette-di-scope.git