关于Castle IOC容器自动装配的问题

今天有一个“27745754”的朋友对Castle IOC容器的自动装配提出了疑问,如果有多个类(组件)实现同一个接口(服务),它会自动选择哪个来进行装配?很多朋友应该都有这样的问题,这里特别说明一下。

还是以我在Castle IOC容器快速入门里用到的日志记录组件为例,现在我们对于ILogFormatter接口:

/// <summary>

/// Author:Terrylee

/// From:http://terrylee.cnblogs.com

/// </summary>


public interface ILogFormatter
{
    
string Format(string MsgStr);
}

它有两个实现,分别为:TextFormatterPlanFormatter

/// <summary>

/// Author:Terrylee

/// From:http://terrylee.cnblogs.com

/// </summary>


public class TextFormatter : ILogFormatter
{
    
public TextFormatter()
    
{

    }


    
public string Format(string MsgStr)
    
{
        
return "[" + MsgStr + "]";
    }

}

 

/// <summary>

/// Author:Terrylee

/// From:http://terrylee.cnblogs.com

/// </summary>


public class PlanFormatter : ILogFormatter
{
    
public PlanFormatter()
    
{

    }


    
public string Format(string MsgStr)
    
{
        
return "{" + MsgStr + "}";
    }

}

再来看一下,在日志记录组件中,它依赖于ILogFormatter

/// <summary>

/// Author:Terrylee

/// From:http://terrylee.cnblogs.com

/// </summary>


public class TextFileLog : ILog
{
    
private string _target;

    
private ILogFormatter _format;

    
public TextFileLog(string target,ILogFormatter format)
    
{
        
this._target = target;

        
this._format = format;
    }


    
public void Write(string MsgStr)
    
{
        
string _MsgStr = _format.Format(MsgStr);

        _MsgStr 
+= _target;


        
//Output Message

        Console.WriteLine(
"Output "+_MsgStr);
    }

}

那么当我们在容器中加入组件后,它会自动装配TextFormatter还是PlanFormatter呢?以事实说话,先来看一下运行的结果吧:

/// <summary>

/// Author:Terrylee

/// From:http://terrylee.cnblogs.com

/// </summary>


public class App
{
    
public static void Main()
    
{
        
//建立容器

        IWindsorContainer container 
= new WindsorContainer( new XmlInterpreter("http://www.cnblogs.com/BasicUsage.xml") );

        
//加入组件

        container.AddComponent(
"txtLog"

            
typeof(ILog), typeof(TextFileLog));

        container.AddComponent(
"planformat"

            
typeof(ILogFormatter), typeof(PlanFormatter));

        container.AddComponent(
"txtformat"

            
typeof(ILogFormatter), typeof(TextFormatter));

        
//获取组件
        ILog log = (ILog) container["txtLog"];

        
//使用组件
        log.Write("First Castle IOC Demo");

        Console.ReadLine();
    }

}

运行程序,结果如下:

Output {First Castle IOC Demo}log.txt

也就是说,它自动装配了PlanFormatter,再调整一下加入组件到容器中的顺序:

/// <summary>

/// Author:Terrylee

/// From:http://terrylee.cnblogs.com

/// </summary>


public class App
{
    
public static void Main()
    
{
        
// 建立容器
        IWindsorContainer container = new WindsorContainer( new XmlInterpreter("http://www.cnblogs.com/BasicUsage.xml") );

        
// 加入组件
        container.AddComponent("txtLog"

            
typeof(ILog), typeof(TextFileLog));


        
// 注意这里调整了顺序
        container.AddComponent("txtformat"

            
typeof(ILogFormatter), typeof(TextFormatter));

        container.AddComponent(
"planformat"

            
typeof(ILogFormatter), typeof(PlanFormatter));

        
// 获取组件
        ILog log = (ILog) container["txtLog"];

        
// 使用组件
        log.Write("First Castle IOC Demo");

        Console.ReadLine();
    }

}

再次运行,出现了下面的结果:

Output [First Castle IOC Demo]log.txt

这次自动装配的是TextFormatter。由这两次的结果我们可以得出:

如果有多个类(组件)实现同一个接口(服务),容器会自动选择最先加入到容器中的组件来装配。对于这样的结果,其实我们并不感觉到意外,每次注册组件时,容器都会检测它的依赖性,当加入第一个ILogFormatter的组件时,容器检测到TextFileLog已经满足了它的依赖性,所以它不会再去装配第二个。


相关参考:

Castle IOC容器快速入门

Castle IOC容器内幕故事(上)

Castle IOC容器内幕故事(下)

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2006-05-25 14:00 TerryLee 阅读(2581) 评论(9)  编辑 收藏 网摘 所属分类: [12]  开源世界[09]  依赖注入

  回复  引用    
#1楼 2006-05-25 15:33 | hevita [未注册用户]
[url=http://www.sina.com.cn] 新浪[/url]
<a href="http://www.sina.com.cn">新浪</a>
  回复  引用    
#2楼 2006-05-25 15:37 | 27745754 [未注册用户]
多谢 多谢 继续关注该系列文章,多多指教
  回复  引用  查看    
#3楼 [楼主]2006-05-25 16:04 | TerryLee      
@27745754

呵呵,太客气了

大家共同交流吧

你提的这个问题确实很有代表性^_^
  回复  引用    
#4楼 2006-07-22 05:12 | JM [未注册用户]
Very brief and clear. Thanks.
  回复  引用  查看    
#5楼 2006-09-14 10:00 | 认真每一天      
这个问题我也发现了,并且通过跟lz差不多的例子验证了一下,确实是这样。所以当有多个组件实现相同的service时,还是需要手动来绑定自己想要的组件。可以在接口中添加一个:
ILogFormat Format{set; get;}



  回复  引用    
#6楼 2006-09-29 17:30 | codelover [未注册用户]
.net开源框架qq交流群30017484,Castle ActiveRecord、Nhibernate、ibatisnet、IOC容器Spring.Net和Castle等框架讨论
  回复  引用    
#7楼 2006-12-21 17:52 | kknd [未注册用户]
我想得到实现了某个接口的所有组件,应该如何操作?
  回复  引用  查看    
#8楼 2007-04-14 18:53 | levinknight      
樓上的,你要用到的時候自己加載一下啊




标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-10-28 13:32 编辑过
Google站内搜索

相关文章:

相关链接: