关于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容器内幕故事(下)

posted @ 2006-05-25 14:00  TerryLee  阅读(4833)  评论(9编辑  收藏  举报