使用自定义参数注入变量而不创建2个guice助手界面? [英] Inject variable with custom parameter without creating 2 guice helper interfaces?

查看:188
本文介绍了使用自定义参数注入变量而不创建2个guice助手界面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用guice动态地在我的构造函数中注入类。例如:

  @Inject 
public PublisherFrame(EventBus eventBus,MyPublisherService publishService)

在我的guice模块中:

 绑定(EventBus.class)。在(Singleton.class); 
bind(MyPublisherService.class).in(Singleton.class);

工作没有问题。



当我创建一个具有java代码构造的参数的对象时,开始:

  public LoginController(EventBus eventBus,MyPublisherService publisherService, LoginDialog dlg)

这里LoginDialog是java代码创建的一个java类。为了解决这个问题,我使用@assist和:

  install(new FactoryModuleBuilder()。implement(ILoginController.class,LoginController.class) .build(GuiceLoginControllerFactory.class)); 

工作也很好。但现在我必须创建2个额外的java文件:




  • LoginController的新界面:ILoginController,除了帮助guice 。

  • 另一个用于guice的界面:GuiceLoginControllerFactory



有更简单的方法来注入变量在构造函数中有一个自定义参数? (不创建2个额外的guice帮助文件)

解决方案

您实际上不需要类本身的附加接口见下文)。此外,我通常创建我的工厂作为它创建的类的嵌套接口:

  public class LoginController {
public界面工厂{
LoginController create(LoginDialog dlg);
}

@Inject public LoginController(
EventBus eventBus,
MyPublisherService publisherService,
@Assisted LoginDialog dlg){/ * ... * /}
}

//在你的模块
install(new FactoryModuleBuilder()。build(LoginController.Factory.class));

您不需要调用 FactoryModuleBuilder.implement 除非你希望Factory的工厂方法的返回类型是一个接口而不是一个具体的类 - 否则Guice将不知道在没有你的帮助的情况下构建什么样的具体类型。在下面的示例中,您不能要求FactoryModuleBuilder为您简单实现 LoginService.Factory ,因为它不知道具体的LoginService实现者要实例化:

  interface LoginService {
interface Factory {
LoginService create(NetConnection connection);
}
boolean login(String username,String password);
}

class SimpleLoginService实现LoginService {
@Inject SimpleLoginService(@Assisted NetConnection连接){/ * ... * /}
}

class SecuredLoginService实现LoginService {
@Inject SecuredLoginService(
EncryptionService encryptionService,
@Assisted NetConnection连接){/ * ... * /}
}

//在你的模块中:实现LoginService.Factory
install(new FactoryModuleBuilder()
.implement(LoginService.class,SimpleLoginService.class)
.build(LoginService.Factory。类));
//这个实现@Secured LoginService.Factory
install(new FactoryModuleBuilder()
.implement(LoginService.class,SecuredLoginService.class)
.build(Key.get LoginService.Factory.class,Secured.class));

除此之外, em>创建一个setter方法的想法并不错,虽然这意味着你正在以部分初始化的状态构建你的类。


I'm using guice to dynamically inject classes in my constructors. For example:

@Inject
public PublisherFrame(EventBus eventBus, MyPublisherService publishService)

And in my guice module:

bind(EventBus.class).in(Singleton.class);
bind(MyPublisherService.class).in(Singleton.class);

Works without problems.

The problem starts when i create a object which has a parameter which is constructed in java code:

public LoginController(EventBus eventBus, MyPublisherService publisherService, LoginDialog dlg)

Here LoginDialog is a java class which java codes create. To solve this i use @assist and:

install(new FactoryModuleBuilder().implement(ILoginController.class, LoginController.class).build(GuiceLoginControllerFactory.class));

Works also nicely. But now i have to create 2 extra java files:

  • a new interface for LoginController: ILoginController, which doesn't do anything except help guice.
  • another interface for guice: GuiceLoginControllerFactory

Is there an easier way to inject a variable which has a custom parameter in the constructor? (without creating 2 extra "guice" helper files)

解决方案

You don't actually need the additional interface for the class itself (see below). Furthermore, I generally create my factory as a nested interface of the class it creates:

public class LoginController {
  public interface Factory {
    LoginController create(LoginDialog dlg);
  }

  @Inject public LoginController(
      EventBus eventBus,
      MyPublisherService publisherService,
      @Assisted LoginDialog dlg) { /* ... */ }
}

// in your module
install(new FactoryModuleBuilder().build(LoginController.Factory.class));

You don't need to call FactoryModuleBuilder.implement unless you want your Factory's factory method's return type to be an interface rather than a concrete class--then Guice won't know what kind of concrete type to construct without your help. In the example below, you couldn't ask FactoryModuleBuilder to simply implement LoginService.Factory for you, as it would have no idea which concrete LoginService implementor to instantiate:

interface LoginService {
  interface Factory {
    LoginService create(NetConnection connection);
  }
  boolean login(String username, String password);
}

class SimpleLoginService implements LoginService {
  @Inject SimpleLoginService(@Assisted NetConnection connection) { /* ... */ }
}

class SecuredLoginService implements LoginService {
  @Inject SecuredLoginService(
      EncryptionService encryptionService,
      @Assisted NetConnection connection) { /* ... */ }
}

// in your module: implements LoginService.Factory
install(new FactoryModuleBuilder()
    .implement(LoginService.class, SimpleLoginService.class)
    .build(LoginService.Factory.class));
// this one implements @Secured LoginService.Factory
install(new FactoryModuleBuilder()
    .implement(LoginService.class, SecuredLoginService.class)
    .build(Key.get(LoginService.Factory.class, Secured.class));

Barring that, condit's idea of creating a setter method isn't bad, though that does mean that you are constructing your class in a partially-initialized state.

这篇关于使用自定义参数注入变量而不创建2个guice助手界面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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