Tapestry:在运行时注入

时间:2016-08-22 16:36:57

标签: java service dependencies code-injection tapestry

通过理解“挂毯如何工作”再次成为一个小问题。

我有一个Tapestry组件(在本例中是一个值编码器):

public class EditionEncoder implements ValueEncoder<Edition>, ValueEncoderFactory<Edition> {

    @Inject
    private IEditionManager editionDao;

    public EditionEncoder(IEditionManager editionDao) {
        this.editionManager = editionDao;
    }

    @Override
    public String toClient(Edition value) {
        if(value == null) {
            return "";
        }
        return value.getName();
    }

    @Override
    public Edition toValue(String clientValue) {
        if(clientValue.equals("")) {
            return null;
        }
        return editionManager.getEditionByName(clientValue);
    }

    @Override
    public ValueEncoder<Edition> create(Class<Edition> type) {
        return this;
    }
}

注入管理器不起作用,因为编码器是在如下页面中创建的:

 public void create() {
        editionEncoder = new EditionEncoder();
  }
由此引发的,我被迫使用这个丑陋的解决方案:

@Inject
private IEditionManager editionmanager;
editionEncoder = new EditionEncoder(editionManager);

有没有更好的方法在运行时注入组件,或者是否有更好的解决方案呢?

提前感谢您的帮助,

1 个答案:

答案 0 :(得分:0)

一旦你使用“new”,那么tapestry-ioc就不会参与对象的创建,也无法注入。您应该注入所有内容,而不要将“new”用于单例服务。对于所有ioc容器都是如此,而不仅仅是tapestry-ioc。

此外,如果您将@Inject放在某个字段上,那么您也不需要构造函数来设置它。做一个或另一个,从不两者兼而有之。

你应该这样做:

public class MyAppModule {
    public void bind(ServiceBinder binder) {
        binder.bind(EditionEncoder.class);
    }
}

然后在您的页面/组件/服务

@Inject EditionEncoder editionEncoder;

如果你想把你自己的实例化对象放在那里,你可以做

public class MyServiceModule {
    public void bind(ServiceBinder binder) {
        binder.bind(Service1.class, Service1Impl.class);
        binder.bind(Service2.class, Service2Impl.class);
    }
    public SomeService buildSomeService(Service1 service1, Service2 service2, @AutoBuild Service3Impl service3) {
        Date someDate = new Date();
        return new SomeServiceImpl(service1, service2, service3, someDate);
    }
}