当前位置: 动力学知识库 > 问答 > 编程问答 >

dependency injection - Is it "bad practice" to pass argument to guice module

问题描述:

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.

Is this a ok use of guice?

网友答案:

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

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.

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.

分享给朋友:
您可能感兴趣的文章:
随机阅读: