是否 "bad practice" 将参数传递给 guice 模块

Is it "bad practice" to pass argument to guice module

查看 Guice,我喜欢它。我目前遇到问题,guice 通过注入我需要的所有必需依赖项来解决它。但我想知道我是否以错误的方式使用了 Guice。不过,我需要的是根据特定实例定义绑定。为了实现这一点,我在模块中传递了实例。

例如,考虑以下问题(有点类似于我的问题):

public class CustomerModule extends AbstractModule { 
   private Customer customer;

   public CustomerModule(Customer customer){
       this.customer = customer;
   }  

   @Override 
   public void configure() {
      bind(ReportGenerator.class).to(HtmlReportGenerator.class);
   }

   @Provides 
   Account providePurchasingAccount() { 
      return customer.getPurchasingAccount();
   }
}

我使用此模块将帐户依赖项注入需要特定客户帐户的报告生成器 class。例如,用户选择特定客户并说,想要显示生成的报告。我有像

这样的方法
public void printReport (Customer customer){
   Injector injector = Guice.createInjector(new CustomerModule(customer));
   ReportGenerator reportGenerator  = injector.getInstance(ReportGenerator.class);

   showReport(reportGenerator.generate())
}

工作完成后,我就完成了这个模块。

可以使用 guice 吗?

接受模块的构造函数参数是合适且有用的。 在为类似对象进行绑定时,这是一种特别常见的模式。示例:

// Installs @Named("accounts") Db to the given impl, backed with the given cache.
install(new DbModule("accounts", AccountDb.class, InMemoryCache.class));
// Same as above.
install(new DbModule("users", UserDb.class, DiskCache.class));
install(new DbModule("products", ProductDb.class, CustomProductCache.class));

也就是说,每个操作创建一个新的根注入器并不常见(例如printReport)。注入器的创建可能需要很长时间,因为 Guice 会反射性地查询 类 及其依赖项。相反,更常见的做法是在应用程序启动时创建根 Injector,然后在需要以现有方式绑定特定对象时创建 child injector

虽然为每个操作临时创建一个全新的根注入器可能是有意义的,但请记住,未来的开发可能会保证 单例或应用程序级范围 持续存在超过单个操作,或者您的对象图可能会增长,以至于中间操作根注入器创建的性能不再足以满足您的使用需求。 If/when 如果发生这种情况,您可能希望将大部分 Injector 创建和配置转移到可预测的启动流程,并且只将您的客户(而不是其他任何东西)绑定到子注入器。