Castle IOC容器与Spring.NET配置之比较

我本人对于Spring.NET并不了解,本文只是通过一个简单的例子来比较一下两者配置之间的区别。在Castle IOC容器中,提出了自动装配(Auto-Wiring)的概念,即由容器自动管理组件之间的依赖关系,我们无需自己编写XML配置文件来配置组件之间的依赖关系。在Spring.NET中也是支持自动装配的,但是并不推荐使用,它贯穿着一种思想就是一切皆为XML配置,这是两者之间最大的一个区别。

关于自动装配,来自于Spring.NET的支持者认为让容器自动管理,会让我们无法控制组件的依赖关系,如果该为XML配置,可以让我们知道自己在做什么,我们指定了哪些依赖关系,方便进行控制和管理;而来自于Castle IOC的支持者认为如果不让容器自动管理,手工配置会变得非常之复杂,配置文件也会变得非常繁冗,如果系统中的组件非常之多的时候,管理工作会变得很困难。

我们来看一个简单的例子,有这样一个组件MyMainComponent,它依赖于MyComponent1MyComponent2,并且它在构造函数中还需要接收一个整型的参数。

//出处:http://terrylee.cnblogs.com

public class MyMainComponent
{
    MyComponent1 _com1;

    MyComponent2 _com2;

    
int _i;

    
public MyMainComponent(MyComponent1 com1,MyComponent2 com2,int i)
    
{
        
this._com1 = com1;

        
this._com2 = com2;

        
this._i = i;
    }

}


public class MyComponent1
{
    
public MyComponent1()
    
{
        
//
    }

}


public class MyComponent2
{
    
public MyComponent2()
    
{
        
//
    }

}


如果用采用Spring.NET,它采用XML进行组件之间的连接,配置文件如下,需要在配置文件中指定每一个对象及其它们之间的依赖,同时在配置文件中区分是构造函数还是其他方法:

<!--出处:http://terrylee.cnblogs.com-->

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

    
<object id="myManComponent" class="CastleDemo.MyMainComponent, CastleDemo">

        
<constructor-arg>

            
<ref object="mycomponent1" />

        
</constructor-arg>

        
<constructor-arg>

            
<ref object="mycomponent2" />

        
</constructor-arg>

        
<constructor-arg>

            
<value>1</value>

        
</constructor-arg>

    
</object>

    
<object id="mycomponent1" class="CastleDemo.MyComponent1, CastleDemo" />

    
<object id="mycomponent2" class="CastleDemo.MyComponent2, CastleDemo" />

</configuration>


Castle IOC中同样需要配置文件,但相比之下,就简单了很多:

<!--出处:http://terrylee.cnblogs.com-->

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

    
<components>

        
<component id="myMainComponent">

            
<parameters>

                
<i>1</i>

            
</parameters>

        
</component>

    
</components>

</configuration>


Castle IOC中的配置并不需要指定组件之间的关联,它会自动通过Windsor来处理;我们只是配置了一个参数i,这个iMyMainComponent中的构造函数中不存在依赖关系的那个参数。

//出处:http://terrylee.cnblogs.com

public class App
{
    
public static void Main()
    
{
        IWindsorContainer container 
= new WindsorContainer(new XmlInterpreter("../../BasicUsage.xml") );

        container.AddComponent( 
"myMainComponent"

            
typeof(MyMainComponent));

        container.AddComponent( 
"myComponent1"

            
typeof(MyComponent1));

        container.AddComponent( 
"myComponent2"

            
typeof(MyComponent2));          

    }

}

这样添加组件后,WindsorContainer会自动调用MicroKernel中的ConstructorDependenciesModelInspector来处理组件的构造函数依赖。

通过上面的这个简单例子比较可以看出,如果我们想要增加一个组件之间的依赖关系或者增加一个组件使用Castle要比使用Spring.NET容易很多,Spring.NET复杂的配置文件会给我们开发带来很来不可预料的错误;Castle根据对象的依赖关系,采用自动装配,不需要配置组件的依赖,另外为了符合构造注入和属性注入,Castle的配置文件并没有像Spring.Net那样区分构造函数还是其他的方法,同时直接使用Parameters,而不是使用构造函数参数之类的区分。

 

参考资料

Castle的官方网站http://www.castleproject.org

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2006-04-25 08:35 TerryLee 阅读(18488) 评论(17) 编辑 收藏

 回复 引用 查看   
#1楼 2006-04-25 14:29 皇帝的新装      
是的。可惜的是还要写一些代码。而且还需要在代码中指定类型。这同样会带来问题。
 回复 引用 查看   
#2楼[楼主] 2006-04-25 14:38 Terrylee      
@皇帝的新装
个人觉得Castle在这方面已经做的很优秀了,不写代码是不可能的^_^

比起Spring.NET那样复杂的配置来说,Castle已经简化了许多!

 回复 引用   
#3楼 2006-04-25 20:42 wt[未注册用户]
确实是这样,配置出错才叫人郁闷呢。
 回复 引用 查看   
#4楼[楼主] 2006-04-26 08:28 Terrylee      
@wt

嗯,尤其这种配置比较复杂的,调试起来特别困难

 回复 引用   
#5楼 2006-07-20 09:16 Joohn[未注册用户]
在配置中实现也是比较容易理解的。
 回复 引用 查看   
#6楼[楼主] 2006-07-20 10:14 TerryLee      
@Joohn

并不是说配置不容易理解,而是因为因为配置增加了很多的复杂性!

 回复 引用   
#7楼 2006-08-15 20:00 slimxxxx[未注册用户]
这样不就像pico一样了?
还是觉得spring更符合ocp原则 ,对代码要尽可能的封闭变化!

 回复 引用   
#8楼 2006-12-08 10:55 飞飞[未注册用户]
是不是配置的参数节点名称必须和代码中的参数名一样才行?
 回复 引用   
#9楼 2007-06-20 10:01 FastSpring[未注册用户]
http://www.springframework.cn/

对Spring.NET有兴趣可以去看看,一定有不少的收获。相信我。不会骗你。

FastSpring.NET V2.0已经发布。

一个集成Spring.Net & NHibernate的框架。

 回复 引用 查看   
#10楼 2007-10-25 23:21 watson      
看了作者的不少文章,受益匪浅,谢谢!
 回复 引用 查看   
#11楼 2008-04-15 21:51 土星的狗狗      
真是不错
 回复 引用   
#12楼 2009-08-08 08:26 liangfeilong[未注册用户]
楼主一定是不知道什么叫控制反转,呵呵。把依赖放到代码里面,我实在想不明白,这样的高度耦合有什么用?
 回复 引用 查看   
#13楼 2009-10-27 18:40 推土机soft      
自动装配会不会带来功能上的限制啊,一般来说,太过自动化的,就只能完成一些基本功能。
不过spring.net的配置确实TMD烦人,但从依赖注入来讲,感觉不如配置文件+反射来的方便呢(基于企业库那套)

 回复 引用 查看   
#14楼 2009-12-02 14:48 WangKai      
看过的您好的文章后,真的学习了不少知识,谢谢
 回复 引用 查看   
#15楼 2010-09-27 00:46 吴X      

博主,配置之比较也太简单了吧。就单单一个自动装配(Auto-Wiring)。
“在Spring.NET中也是支持自动装配的,但是并不推荐使用”,个人觉得这
更好。如果某对象依赖的其它对象太多,你没有明确声明,到最后是不是
让别人很混乱。Spring.net中只要类的属性名称与配置的object的id相同,它就
会自动装配,貌似是这样的。
而且使用时不需要这样的代码:
container.AddComponent( "myMainComponent",
typeof(MyMainComponent));
container.AddComponent( "myComponent1",
typeof(MyComponent1));
container.AddComponent( "myComponent2",
typeof(MyComponent2));
它自动加载并实例化。而且Sprint.NET支持 lazy-init,只有当需要该object
时,它才去加载类并生成对象。
期望博主更深层次的,比较。

 回复 引用 查看   
#16楼 2010-12-01 13:12 Alan@Net      
@Terrylee
@吴X
我也感觉楼主的例子有点问题,可能我还不懂castle吧,我只用过Spring.net

 回复 引用 查看   
#17楼 2012-01-07 21:41 知秋      
AOP的本质是接口,JAVA是基于接口编程的,而NET不太重视,所以来自于JAVA的spring要成熟一些。
container.AddComponent( "myMainComponent",
typeof(MyMainComponent));
container.AddComponent( "myComponent1",
typeof(MyComponent1));
container.AddComponent( "myComponent2",
typeof(MyComponent2));
就是这段代码把AOP彻底毁了,如果myComponent1是个接口,实现这个接口可能是自己的,也可能是第三方的,那么这个时候我需要更换组件,那么castle意味着需要重写代码。