开发者社区> 技术小甜> 正文

Castle IOC容器快速入门

简介:
+关注继续查看
摘要:IOC模式是近年来非常流行的一种模式,相信大家都不陌生了,如果你还不是很熟悉的话,可以看看Martin Fowler大师的文章[url]http://martinfowler.com/articles/injection.html[/url],网上可以下载到中文版本。在Castle中,Windsor就是它的一个IOC容器,它构建于MicroKernel之上,功能非常强大。本文将通过一个简单的例子来带你快速走进Castle IOC容器。
 
主要内容
1.为什么要IOC
2.什么是Castle IOC容器
3.快速入门示例
4.几个重要的概念
 
一,为什么要IOC
IOC(控制反转或者叫依赖注入)Martin Fowler大师在他的文章中已经讲解的非常精彩了,这里实在不敢班门弄斧,只好简单地解释几句。我们使用抽象接口来隔离使用者和具体实现之间的依赖关系,但是不管再怎么抽象,最终还是要创建具体实现类的实例,这种创建具体实现类的实例对象就会造成对于具体实现的依赖,为了消除这种创建依赖性,需要把依赖移出到程序的外部(比如配置文件)。使用依赖注入后,这些类完全是基于抽象接口编写而成的,所以可以最大限度地适应需求的变化。依赖注入的形式有三种,分别为构造子注入(Constructor Injection)、设值方法注入(Setter Injection)和接口注入(Interface Injection)。
 
二.什么是Castle IOC容器
WindsorCastle 的一个IOC容器。它构建于MicroKernel之上,功能非常之强大,能检测类并了解使用这些类时需要什么参数,检测类型和类型之间工作依赖性,并提供服务或者发生错误时提供预警的机制。
 
三.快速入门示例
现在假如我们有这样一个需求,开发一个日志组件,把日志信息输出到文本文件,同时对输出的信息进行格式化,以示意性的代码来实现。
1.新建一个C#工程,添加对以下Dll的引用
Castle.DynamicProxy.dll
Castle.MicroKernel.dll
Castle.Model.dll
Castle.Windsor.dll
2.编写服务
既然是日志组件,我们先添加两个接口分别为ILogILogFormatter,这样的接口我们一般叫做服务,即实现了某种服务的接口(后面会讲到)。
ExpandedBlockStart.gif/// <summary>
InBlock.gif
InBlock.gif
/// 编写:Terrylee
InBlock.gif
InBlock.gif
/// 出处:[url]http://terrylee.cnblogs.com[/url]
InBlock.gif
ExpandedBlockEnd.gif
/// </summary>

None.gif
None.gif
public interface ILog
None.gif
ExpandedBlockStart.gif
{
InBlock.gif
InBlock.gif    
void Write(string MsgStr);
InBlock.gif
ExpandedBlockEnd.gif}

None.gif
 
ExpandedBlockStart.gif/// <summary>
InBlock.gif
InBlock.gif
/// 编写:Terrylee
InBlock.gif
InBlock.gif
/// 出处:[url]http://terrylee.cnblogs.com[/url]
InBlock.gif
ExpandedBlockEnd.gif
/// </summary>

None.gif
None.gif
public interface ILogFormatter
None.gif
ExpandedBlockStart.gif
{
InBlock.gif
InBlock.gif    
string Format(string MsgStr);
InBlock.gif
ExpandedBlockEnd.gif}

3.编写组件
仅仅有接口还不行,还需要实现了上面两个接口的具体实现类,这些类我们把它叫做组件。
ExpandedBlockStart.gif/// <summary>
InBlock.gif
InBlock.gif
/// 编写:Terrylee
InBlock.gif
InBlock.gif
/// 出处:[url]http://terrylee.cnblogs.com[/url]
InBlock.gif
ExpandedBlockEnd.gif
/// </summary>

None.gif
None.gif
public class TextFileLog : ILog
None.gif
ExpandedBlockStart.gif
{
InBlock.gif
InBlock.gif    
private string _target;
InBlock.gif
InBlock.gif    
private ILogFormatter _format;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
public TextFileLog(string target,ILogFormatter format)
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
InBlock.gif        
this._target = target;
InBlock.gif
InBlock.gif        
this._format = format;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
public void Write(string MsgStr)
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
InBlock.gif        
string _MsgStr = _format.Format(MsgStr);
InBlock.gif
InBlock.gif        _MsgStr 
+= _target;
InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif        
//Output Message
InBlock.gif

InBlock.gif        Console.WriteLine(
"Output "+_MsgStr);
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}
 
ExpandedBlockStart.gif/// <summary>
InBlock.gif
InBlock.gif
/// 编写:Terrylee
InBlock.gif
InBlock.gif
/// 出处:[url]http://terrylee.cnblogs.com[/url]
InBlock.gif
ExpandedBlockEnd.gif
/// </summary>

None.gif
None.gif
public class TextFormatter : ILogFormatter
None.gif
ExpandedBlockStart.gif
{
InBlock.gif
InBlock.gif    
public TextFormatter()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
InBlock.gif        
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
public string Format(string MsgStr)
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
InBlock.gif        
return "[" + MsgStr + "]";
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

4.编写配置文件
编写配置文件,由于TextFileLog构造函数中除了需要一个ILogFormatter的实例之外,还需要指定信息的输出的文本文件名,所以编写一个配置文件来指定,这个也可以放在应用程序配置文件中(Web.config或者App.config)。
None.gif<?xml version="1.0" encoding="utf-8" ?>
None.gif
None.gif
<configuration>
None.gif
None.gif    
<components>
None.gif
None.gif        
<component id="txtLog">
None.gif
None.gif            
<parameters>
None.gif
None.gif                
<target>log.txt</target>
None.gif
None.gif            
</parameters>
None.gif
None.gif        
</component>
None.gif
None.gif    
</components>
None.gif
None.gif
</configuration>
 
5.使用Castle IOC容器
前面的几步仅仅是为我们Castle IOC做准备,下面就是正式使用了。使用Castle IOC容器非常简单,基本上分为建立容器,加入组件,获取组件,使用组件几个步骤。
 
ExpandedBlockStart.gif/// <summary>
InBlock.gif
InBlock.gif
/// 编写:Terrylee
InBlock.gif
InBlock.gif
/// 出处:[url]http://terrylee.cnblogs.com[/url]
InBlock.gif
ExpandedBlockEnd.gif
/// </summary>

None.gif
None.gif
public class App
None.gif
ExpandedBlockStart.gif
{
InBlock.gif
InBlock.gif    
public static void Main()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
InBlock.gif        
//建立容器
InBlock.gif

InBlock.gif        IWindsorContainer container 
= new WindsorContainer( new XmlInterpreter("../../BasicUsage.xml") );
InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif        
//加入组件
InBlock.gif

InBlock.gif        container.AddComponent( 
"txtLog"
InBlock.gif
InBlock.gif            
typeof(ILog), typeof(TextFileLog) );
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        container.AddComponent( 
"format"
InBlock.gif
InBlock.gif            
typeof(ILogFormatter), typeof(TextFormatter) );
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        
//获取组件
InBlock.gif

InBlock.gif        ILog log 
= (ILog) container["txtLog"];
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        
//使用组件
InBlock.gif

InBlock.gif        log.Write(
"First Castle IOC Demo");
InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif        Console.ReadLine();
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}
简单的描述一下:
第一步:注册了一个Windsor容器;
第二步:向容器中注册ILog服务,并告诉容器TextFileLog实现了这个服务,这里还设置了一个key的参数,后面可以通过这个参数来获取这个服务,注册ILog时容器会发现这个服务依赖于其他的服务,它会自动去寻找,如果找不到这样的服务,则会抛出一个异常;
第三步:向容器中注册ILogFormatter并告知TextFormatter实现了它;
第四步:容器发现类的构造函数还需要另外一个参数target,这里指定了到BasicUsage.xml中去查找。
运行程序,可以看到输出的结果:
None.gifOutput [First Castle IOC Demo]log.txt
怎么样?够简单的吧。可以看到整个过程非常的简单,代码也非常优雅,我们并没有使用new关键字创建一个具体实现类的实例,至此,一个简单的使用Castle IOC的过程就完成了。下面我们来理解一下其中几个重要的概念。
四.几个重要的概念
1.服务
服务是一个个的接口,接口约定了服务,从而使随意替换服务的实现对使用接口服务的代码没有任何的影响。像我们上面例子中的ILogILogFormatter都是一个个服务,我们在这个例子中支实现了一个文本文件的日志记录,如果你要是实现数据库记录的日志记录,都必须要遵守ILog这个接口。
2.组件
简单来说组件是一个可重用的程序单元,它实现了某个接口,并仅仅只实现了这一个良好的接口。也就是说,组件是实现了某个服务接口的类。像上例中的TextFileLogTextFormatter都是组件
3.自动装配
在上面的例子中,大家可能都已经注意到了,TextFileLog依赖于TextFormatter,我们却没有在配置文件中指定它们之间的依赖关系,这就是Castle IOC聪明的一个地方,它能够自动管理组件之间的依赖关系,而无需编写特定的xml config来配置,即自动装配的意思。
 
Castle IOC容器快速入门指南就到这儿,欢迎大家多多指教,后续文章我会详细的去写Castle IOC及其Facility文中完整的程序:下载
 
参考资料














本文转自lihuijun51CTO博客,原文链接: http://blog.51cto.com/terrylee/67671,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
STL之如何选择顺序容器
一、顺序容器的分类   顺序容器:vector向量、list链表、deque双端队列;   优先级最高的是vector向量,它的速度比较快,优点最多;   在程序设计中,容器可以切换; 1 #include 2 #include 3 #include 4 #inclu...
944 0
福利!阿里宣布手淘安卓客户端容器化框架Atlas正式开源
3月13日,手机淘宝安卓客户端容器化框架Atlas正式宣布开源(https://github.com/alibaba/atlas)。Atlas由阿里巴巴移动团队自研,以容器化思路解决大规模团队协作问题,实现并行开发、快速迭代和动态部署,适用于Android 4.x以上系统版本的大小型App开发。
17401 0
+关注
10140
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载