在 Guice 中管理同一依赖树的多个版本的最佳模式是什么?

2023-11-21

我想实例化同一类型依赖树/链的多个版本,它们对该树/链中的某些接口使用不同的实现。在这种情况下使用的最佳 Guice 实践/模式是什么?

这是我的问题的具体示例。

我有一个Writer接口可能是文件编写器或标准输出编写器,它将位于我的依赖关系层次结构的叶子。像这样的东西:

interface Writer { ... }
class FileWriter implements Writer { ... }
class StdOutWriter implements Writer { ... }

另一个记录器接口用于在编写器上添加一个间接层。例如:

interface Logger { ... }

class LoggerImpl{
  @Inject
  public Logger(Writer out){ ... }
  public void log(String message){ out.println(message); }
}

然后有一个使用记录器的客户端。

class Client{
  @Inject
  public Client(Logger logger){ ... }
  public void do(){ logger.log("my message"); }
}

现在,我想在我的程序中使用两种类型的层次结构:

  1. 客户端 -> LoggerImpl -> FileWriter
  2. 客户端 -> LoggerImpl -> StdOutWriter

有没有一种好的方法可以在不为 1 和 2 使用单独的 Guice 模块的情况下进行连接?

理想情况下我希望有一个ClientFactory像这样的类:

interface ClientFactory{
  public Client stdOutClient();
  public Client fileClient(); 
  //or fileClient(File outputFile) for extra points ;)
}

任何人都可以想出一种方法来使用这个工厂或通过任何其他方式来连接它吗?

我还想要一个可以扩展到我有更多种类的较长依赖树/链的情况的解决方案。谢谢!


这是机器人腿问题。解决办法基本上就是使用私有模块绑定每个依赖树并仅公开该树的根。您可以通过多种方法来执行此操作,但以下是您通常可以如何执行此操作的示例(您可以根据需要执行多种操作):

public class ClientModule extends PrivateModule {
  private final Writer writer;
  private final Class<? extends Annotation> annotationType;

  public ClientModule(Writer writer, Class<? extends Annotation> annotationType) {
    this.writer = writer;
    this.annotationType = annotationType;
  }

  @Override protected void configure() {
    bind(Writer.class).toInstance(writer);
    bind(Logger.class).to(LoggerImpl.class);
    expose(Client.class).annotatedWith(annotationType);
  }
}

public class ClientFactoryModule extends AbstractModule {
  private final File file;

  public ClientFactoryModule(File file) {
    this.file = file;
  }

  @Override protected void configure() {
    install(new ClientModule(new StdOutWriter(), StdOut.class));
    install(new ClientModule(new FileWriter(file), FileOut.class));
    bind(ClientFactory.class).to(ClientFactoryImpl.class);
  }
}

public class ClientFactoryImpl implements ClientFactory {
  private final Client stdOutClient;
  private final Client fileClient;

  @Inject public ClientFactoryImpl(@StdOut Client stdOutClient, 
                                   @FileOut Client fileClient) {
    this.stdOutClient = stdOutClient;
    this.fileClient = fileClient;
  }

  ...
}

您的方法场景Client fileClient(File)但还是有一点不同。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Guice 中管理同一依赖树的多个版本的最佳模式是什么? 的相关文章

随机推荐

  • 如何将 puppeteer-core 与 electro 结合使用?

    我从另一个 Stackoverflow 问题中得到了这段代码 import electron from electron import puppeteer from puppeteer core const delay ms number
  • max_input_vars 设置即使在 php.ini 中注释

    我的 PHP 应用程序有一个奇怪的问题 在我的 php ini 中 我已经注释掉了max input vars指令 但是当提交 1 2k 表单时 我知道它有点大 最后 200 个帖子值被截断 奇怪的是我什至重新启动了我的 Apache 我的
  • 不同 .config 文件上的 AppSettings 未更新

    我正在尝试做与最近提到的完全相同的事情上一个问题 本质上 情况是这样的 这与我的情况完全相同 我的计划是拥有这些 appSettings 在他们自己的文件 Settings config 中 我将授予修改权 Web进程用户的权限 帐户 并存
  • 在 C++ 中将数组的所有元素初始化为一个默认值?

    C 笔记 数组初始化有一个关于数组初始化的很好的列表 我有一个 int array 100 1 期望它充满 1 但事实并非如此 只有第一个值是 其余的都是 0 与随机值混合 The code int array 100 0 工作正常并将每个
  • android 在同一个活动中添加两个工具栏?

    我有一个底部菜单作为工具栏 我需要在顶部添加另一个菜单作为操作栏 这是活动的代码 public class ListViewPharms extends AppCompatActivity public Toolbar mToolbar L
  • hibernate复合主键包含复合外键,如何映射这个

    我在那里搜索 没有找到任何类似的主题 所以我发布了一个新问题 我正在现有数据库上使用 Hibernate 我们不允许更改表结构和数据 应用程序从数据库读取数据并根据某种逻辑迁移到另一个数据存储 现在的问题是关于复合 PK 映射 例如 表 A
  • Flux 未在 Spring 5 Reactor 中订阅

    我可能错过了一些东西 但我不知道它是什么 下面的代码什么也不做 webClient get uri some path here retrieve bodyToMono GetLocationsResponse class doOnNext
  • 如何获取充当 stdin/stdout 的文件的名称?

    我遇到以下问题 我想用 Fortran90 编写一个程序 我希望能够像这样调用 program x lt main in gt main out 除了 main out 我可以在调用程序时设置其名称 之外 还必须编写辅助输出 我希望它们具有
  • java rmi中的通信安全吗?

    java rmi 中客户端和服务器之间的通信是否安全 即默认加密 编码 是的 加密的 没有 JERI for JINI 提供基于 SSL IIRC 的 JRMP RMI 协议 JSR 76 本来可以提供 RMI 安全性 但它是有争议的被否决
  • 在不知道急救人员的情况下隐藏 iPhone 上的输入键盘?

    我见过这个问题 但问题是如何知道哪个textView是第一响应者 这个问题看起来很有希望找出第一响应者 但事实证明它调用了私有 API 有没有办法隐藏键盘或找出第一响应者作为拥有键盘的人 这很容易 UIApplication sharedA
  • 向 VB.Net 应用程序添加命令行参数

    我有一个由另一位程序员制作的基于 Windows 窗体的应用程序 我需要向其添加一些命令行开关primary output exe这样我就可以传递如下参数 program exe reinitialise or program exe sy
  • Django ImageField 验证(是否足够)?

    我有很多用户上传的内容 我想验证上传的图像文件实际上不是恶意脚本 在 Django 文档中 它指出 ImageField 继承 FileField 的所有属性和方法 但也验证上传的对象是有效的图像 这完全准确吗 我读到压缩或以其他方式操作图
  • Verilog 显示中不必要的空间

    我正在尝试以十进制显示一些 32 位值 除了 b 和前一个字符之间有奇怪数量的不必要的空格外 这工作正常 例如 如果我有一个 32 位 reg a 其十进制值为 33 我将使用类似的东西 initial begin display a d
  • GetMaxAmplitude 的值范围

    我有一个有趣的想法 可以在 Android 手机上开箱即用地使用麦克风端口 我正在集思广益如何使用 Android 手机记录咖啡烘焙机内的烘焙温度 这个想法突然出现在我的脑海中 麦克风是低压的 我的热电偶也是低压的 所以我开始研究 andr
  • 如何将图像视图从一个活动发送到另一个活动

    我在第一个活动的列表视图中有一个图像视图 我想通过单击列表视图项目将我的图像视图发送到第二个活动 我尝试过以下代码 将可绘制图像转换为字节数组 Bitmap bmp BitmapFactory decodeResource getResou
  • 在 VSTS 构建和发布中排除/跳过文件

    我们正在为 VSTS CI CD 创建架构 以将我们的 Web 应用程序部署到 Azure 应用服务 我们希望在将 web config 部署到 Azure 服务器时排除它 因为我们直接修改不同环境中的 web config CI 任务如下
  • Seaborn 混淆矩阵(热图)2 种配色方案(正确的对角线与错误的其余部分)

    背景 在混淆矩阵中 对角线表示预测标签与正确标签匹配的情况 所以对角线是好的 而所有其他单元格都是坏的 为了向非专家阐明 CM 的优点和缺点 我想为对角线赋予与其他部分不同的颜色 我想通过以下方式实现这一目标Python 和 Seaborn
  • Android 版 OpenCV - 访问 Mat 的元素

    在 OpenCV4Android 中访问和修改 Mat 的各个元素的标准方法是什么 另外 BGR 我认为这是默认值 和灰度的数据格式是什么 编辑 让我们更具体一些 mat get row col 返回一个双精度数组 这个数组里有什么 如果您
  • 构建设置中缺少 Xcode 12 beta 有效架构

    Hi I m using Xcode Version 12 0 beta 3 12A8169g Valid architectures in build settings is missing Does anybody know how t
  • 在 Guice 中管理同一依赖树的多个版本的最佳模式是什么?

    我想实例化同一类型依赖树 链的多个版本 它们对该树 链中的某些接口使用不同的实现 在这种情况下使用的最佳 Guice 实践 模式是什么 这是我的问题的具体示例 我有一个Writer接口可能是文件编写器或标准输出编写器 它将位于我的依赖关系层