将参数传递给guice模块是“不好的做法”

时间:2016-03-06 22:56:35

标签: dependency-injection guice

检查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();
   }
}

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

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

   showReport(reportGenerator.generate())
}

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

这是否可以使用guice?

1 个答案:

答案 0 :(得分:5)

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

// 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));

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

虽然您可能有意义为每个操作临时创建一个全新的根注入器,但是您可以采用它的方式,请记住未来的开发可能会使权证单例或应用程序级范围持续存在于单个操作之外,或者您的对象图可能会增长,使得中间操作根注入器创建不再具有足够的性能供您使用。如果/何时发生这种情况,您可能希望将大多数Injector创建和配置转移到可预测的启动流程,并且只将您的客户(以及其他任何内容)绑定到子注入器中。