精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2005-04-06
Readonly 写道 在SetterInjectionComponentAdapterTestCase.testAllUnsatisfiableDependenciesAreSignalled
里面, 为什么一定要在Container里面注册一个List给A? 如果只想让Container通过setter为A注入已经存在的components, 应该怎么写代码? 这样: Component aAdapter = Components.bean(A.class); .withProperty("list", Components.value(mylist););; .... |
|
返回顶楼 | |
发表时间:2005-04-06
可那是偶没有讲清楚, 用代码来说吧:
public class Bar { } public class Foo { private Bar bar; private List list; //getters and setters ... } 应该如何写才能让这个测试代码通过: public testSingletonAndUnCompleteSetterInjection { YanContainer c = new DefaultContainer();; c.registerComponent("bar", Components.bean(Bar.class);.singleton(););; c.registerComponent("foo", Components.bean(Foo.class);.singleton(););; Foo f1 = (Foo); c.getInstance("foo");; Foo f2 = (Foo); c.getInstance("foo");; assertSame(f1, f2);; assertNull(f1.getList(););; } 偶上面的代码, 在getInstance的时候报错, 说foo的list属性为空...... |
|
返回顶楼 | |
发表时间:2005-04-06
你的意思是这个list的property不用?
只set bar这个property? 可以这样: public testSingletonAndUnCompleteSetterInjection { YanContainer c = new DefaultContainer();; c.registerComponent("bar", Components.bean(Bar.class);.singleton(););; c.registerComponent("foo", Components.bean(Foo.class, new String[]{"bar"});.singleton(););; Foo f1 = (Foo); c.getInstance("foo");; Foo f2 = (Foo); c.getInstance("foo");; assertSame(f1, f2);; assertNull(f1.getList(););; } 用bean(Foo.class, new String[]{"bar"})来表示只设置bar属性。 这是如果你干脆不希望调用setList。 而如果你希望给它set成null,那么这样: bean(Foo.class);.withProperty("list", Components.value(null););; 如果这再报错,那就是我的bug了。 |
|
返回顶楼 | |
发表时间:2005-04-06
嗯, 偶的目的就是干脆不希望调用setList, 容器只调用它已经注册的东东给setter注入.
按照你的写法确实可以pass, 但是容器应该支持不完整的autowire, spring好像没有yan这种怪异的setter要求啊 (pico的setter机制有么?) |
|
返回顶楼 | |
发表时间:2005-04-06
同意Readonly的说话.被wire的对象是受者,别人不给它,默认就表示不满不好。spring里bean通过实现InitializingBean接口来做检查。
|
|
返回顶楼 | |
发表时间:2005-04-06
Readonly 写道 嗯, 偶的目的就是干脆不希望调用setList, 容器只调用它已经注册的东东给setter注入.
按照你的写法确实可以pass, 但是容器应该支持不完整的autowire, spring好像没有yan这种怪异的setter要求啊 (pico的setter机制有么?) 你的意思就是说,缺省情况,容器如果找不到一个合适的组件给某个property,就自动pass过去? 这也可以作。只不过,我觉得这样损害了predictability。一个bean的哪个property被注射了都不知道,完全依赖于容器这个全局环境。 也许某个developer自己注册了一个组件,还没用呢,却没想到这悄悄改变了程序的其它部分的行为。 与此类似的一个是ctor(Class),pico是在构造函数多于一个的时候选择参数最多的那个,而我是直接报错,我这么选择也是基于predictability的考虑。 不过这也许确实有需求,我在考虑用动态组合子来实现它。 想象中的语法应该这样: Monad.bind( Monad.bind( Components.getProperties(Foo.class); ,filterVisible );, toBean(Foo.class); );; getProperties负责把一个bean class的所有property列出来。 filterVisible是一个Binder对象,负责过滤出可见的所有property。 toBean是另外一个Binder对象,负责根据给定的propety动态产生一个bean component。 麻烦是麻烦,但是你可以写一个函数把上面的代码封装起来。总而言之,我是希望discourage这种太自动的用法。 这可以在下一个版本支持。 |
|
返回顶楼 | |
发表时间:2005-04-06
nihongye 写道 同意Readonly的说话.被wire的对象是受者,别人不给它,默认就表示不满不好。spring里bean通过实现InitializingBean接口来做检查。
关键是怎么区分一个property是否是mandatory? 系统需要一个信息来知道一个property没有被满足是否致命。 spring有自动wire吗?我印象中spring都是一个一个property配置的。 |
|
返回顶楼 | |
发表时间:2005-04-06
ajoo 写道 你的意思就是说,缺省情况,容器如果找不到一个合适的组件给某个property,就自动pass过去? 不过这也许确实有需求,我在考虑用动态组合子来实现它。 嗯,偶的想法就是这样 主要是有实际需求的,所以才有这个想法,比如有个默认值, public class Foo { private boolean useCache = true; private Bar bar; //getters and setters ... } 可以在配置文件里面重载掉: <bean id="foo" class="Foo" autowire="byName"> <property name="useCache"><value>false</value></property> </bean> 也可以选择就使用默认值: <bean id="foo" class="Foo" autowire="byName"/> ajoo 写道 关键是怎么区分一个property是否是mandatory? 系统需要一个信息来知道一个property没有被满足是否致命。 spring有自动wire吗?我印象中spring都是一个一个property配置的。 yan的做法是把这个工作交给了组装代码,对吧? 但是偶对那个测试用例还是有个疑问,为啥string没有被set,它不会抱怨,而list没有被set,就报错呢? |
|
返回顶楼 | |
发表时间:2005-04-07
引用 为啥string没有被set,它不会抱怨
找时间我跑跑你的test case。 不过哪里有个string?你不就是一个bar, 一个list吗? |
|
返回顶楼 | |
发表时间:2005-04-07
用缺省值确实是个需求。必须要显示指定properties也显得不是很方便。
不过让容器ignore我还有很多问题。 首先: 所谓“不满足”,有很多种。 1。组件找不到 2。组件找到了,但是组装它的某个参数或者属性找不到。 3。组装它的参数找到了,但是组装时候又出现了零件找不到的问题 这种unsatisfied情况可以一直cascade下去。 4。二义性。两个组件都提供同一个零件。 5。cyclic dependency 6。type mismatch。 .... 是否容器对所有的错误都ignore?这样会不会对查找错误造成很大的不方便? 如果要允许用户自己选择对哪种情况ignore,哪种情况报错,接口就复杂起来,实现上也复杂了。 其实我本来想实现的MonadPlus,就是说,当一个组件组装失败,选择另一个组件,就是因为错误种类太多,我没有找到一个“什么情况是致命,什么是可恢复”的标准答案,所以至今没有做。 |
|
返回顶楼 | |