这是“不良做法”吗?将参数传递给guice模块 [英] Is it "bad practice" to pass argument to guice module

查看:59
本文介绍了这是“不良做法”吗?将参数传递给guice模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

签出Guice,我很喜欢。我目前有问题,guice通过注入我需要的所有必需依赖关系解决了它。但是我想知道我是否以错误的方式使用了Guice。虽然我需要的是根据特定实例定义绑定。为此,我在模块中传递了实例。

Checking out Guice and I love it. I currently have problem where guice solved it by injecting all the required dependencies I need. But I wonder if I am using Guice in the wrong way. What I require though is define bindings depending on specific instance. And to achieve this I passed the instance in the module.

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

For instance, consider the following (somewhat similar to my problem):

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

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

I use this module to get Account dependency injected to the report generator class that needs the account of a specific customer. For example, a user chooses a specific customer and say, wants to show a generated report. I have method like

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

   showReport(reportGenerator.generate())
}

工作完成后,我将完成此模块。

Once the work is done, I am done with this module.

这可以很好地使用guice吗?

Is this a ok use of guice?

推荐答案

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

It is appropriate and useful to accept a constructor argument for a Module. This is an especially common pattern when making bindings for similar objects. Example:

// 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,然后创建 子注射器 ,当您需要以特定方式绑定特定对象时。

That said, it is not common to create a new root Injector per action (such as printReport). Injector creation can take a long time as Guice reflectively queries classes and their dependencies. Instead, it is much more common to create the root Injector at application startup, and then create a child injector when you need to bind specific objects the way you have them.

尽管您可能需要为每个操作临时创建一个全新的根注入器,但您要注意的是,请记住,未来的发展可能会带来保证单个或应用程序级作用域会持续到单个动作之外,否则您的对象图可能会增长,从而使中间动作根Injector创建不再足以满足您的使用需求。如果/当发生这种情况时,您可能希望将大多数Injector的创建和配置转移到可预测的启动流程,并且仅将Customer(而不是其他)绑定到子注射器中。

Though it may make sense for you to temporarily create a brand new root Injector for each action, the way you have it, bear in mind that future development may make warrant singleton or application-level scope that persists beyond a single action, or your object graph may grow such that mid-action root Injector creation is no longer performant enough for your uses. If/when that happens, you may want to shift most of your Injector creation and configuration to a predictable startup flow, and only bind your Customer (and nothing else) into a child injector.

这篇关于这是“不良做法”吗?将参数传递给guice模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆