我正在尝试使用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。
期待答案,
大卫
答案 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)
);
并适当地装饰了所有类,但我仍然遇到与以前相同的错误。你能否对此有所了解?