ComponentNotFound异常Castle.Windsor

时间:2010-12-20 19:46:40

标签: exception castle-windsor

我正在尝试使用Castle.Windsor,并根据我对当前可用于新手的样本做出的评论(http://stw.castleproject.org/Windsor.Silvertlight_Sample_App_Customer_contact_manager.ashx?Discuss=1),我想我会抓住公牛并更新这里提供的示例http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart1.aspx

这是一个简单而相当简单的控制台应用程序,使用Castle Windsor,尽管它是一个过时的版本。 Program.cs中的My Main方法如下:

public static void Main()
    {
        IWindsorContainer container = new WindsorContainer();

        container.Install(FromAssembly.This());
        var retriever = container.Resolve<IHtmlTitleRetriever>();

        Console.WriteLine(retriever.GetTitle(new Uri(ConfigurationManager.AppSettings["fileUri"])));

        Console.Read();

        container.Dispose();
    }

和服务和组件,它们都在同一个文件中,即Program.cs因此:

public interface IHtmlTitleRetriever
{
    string GetTitle(Uri file);

}

public interface IFileDownloader
{
    string Download(Uri file);
}

public interface ITitleScraper
{
    string Scrape(string fileContents);
}

public class HtmlTitleRetriever: IHtmlTitleRetriever
{
    private readonly IFileDownloader _downloader;
    private readonly ITitleScraper _scraper;

    public HtmlTitleRetriever(IFileDownloader dowloader, ITitleScraper scraper)
    {
        _downloader = dowloader;
        _scraper = scraper;
    }

    public string GetTitle(Uri file)
    {
        string fileContents = _downloader.Download(file);
        return _scraper.Scrape(fileContents);
    }
}



public class HttpFileDownloader : IFileDownloader
{
    public string Download(Uri file)
    {
        return new WebClient().DownloadString(file);
    }
}

public class StringParsingTitleScraper : ITitleScraper
{
    public string Scrape(string fileContents)
    {
        string title = string.Empty;
        int openingTagIndex = fileContents.IndexOf("<title>");
        int closingTagIndex = fileContents.IndexOf("</title>");

        if(openingTagIndex != -1 && closingTagIndex != -1)
            title = fileContents.Substring(openingTagIndex, closingTagIndex - openingTagIndex).Substring(7);

        return title;
    }
}

这几乎是Simone Busoli从他的例子中得到的直接副本。代码编译得很好,但是当我运行应用程序时出现以下错误:

  

找不到支持服务WindsorSample.IHtmlTitleRetriever的组件

我明白这意味着什么,但我不知道我做错了什么,组件没有被加载到容器中。我正在使用Castle.Windsor 2.5.2和.NET 4.0。

期待答案,

大卫

2 个答案:

答案 0 :(得分:0)

首先 - 很棒,你正在更新样本。正如您所提到的,一个更小的样本,没有Silverlight开销肯定会有用。

至于您的问题 - 例外意味着您注册的任何组件都不支持您请求的服务IHtmlTitleRetriever,换句话说 - 您似乎没有注册IHtmlTitleRetriever容器。您的安装程序如何?要检查组件是否正确注册,您可以在调用Install后在行中放置一个断点,并查看已注册的组件,以及这是否是您所期望的。这对于快速诊断您所拥有的问题非常有用。 (see the documentation here)。

如果您仍然不确定原因是什么,请确保您的安装程序类都是公开的,并在此处发布其代码,以便我们可以尝试找出原因。

答案 1 :(得分:0)

遵循Krzysztof的建议,以下是如何让我的简单示例:

 public static void Main()
    {
        var container = new WindsorContainer();

       // container.Install(FromAssembly.This());
        container.Register(
            Component.For( typeof( IHtmlTitleRetriever ) ).ImplementedBy( typeof(HtmlTitleRetriever) ) ,
            Component.For( typeof( IFileDownloader ) ).ImplementedBy( typeof( HttpFileDownloader ) ),
            Component.For( typeof( ITitleScraper ) ).ImplementedBy( typeof( StringParsingTitleScraper ) )
         );
        var retriever = container.Resolve<IHtmlTitleRetriever>();

        Console.WriteLine(retriever.GetTitle(new Uri(ConfigurationManager.AppSettings["fileUri"])));

        Console.Read();

        container.Dispose();
    }

那会有效。


Krzysztof,我们也试过这个

 container.Register(
            AllTypes.FromThisAssembly().Pick().If(Component.IsCastleComponent)
        );

并适当地装饰了所有类,但我仍然遇到与以前相同的错误。你能否对此有所了解?