通过理解“挂毯如何工作”再次成为一个小问题。
我有一个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);
有没有更好的方法在运行时注入组件,或者是否有更好的解决方案呢?
提前感谢您的帮助,
答案 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);
}
}