我有一个使用 Castle Windsor 的富客户端应用程序。目前,包括应用程序 exe 在内的所有程序集都在一个文件夹中,但看起来都很不整洁。我想将我的 dll 放在诸如“bin”之类的子文件夹中,但这会阻止 Castle 在调用时定位类型等。事实上,应用程序在启动时崩溃。
有没有办法告诉 Castle 在其他地方寻找文件?
我有一个使用 Castle Windsor 的富客户端应用程序。目前,包括应用程序 exe 在内的所有程序集都在一个文件夹中,但看起来都很不整洁。我想将我的 dll 放在诸如“bin”之类的子文件夹中,但这会阻止 Castle 在调用时定位类型等。事实上,应用程序在启动时崩溃。
有没有办法告诉 Castle 在其他地方寻找文件?
That depends on how you are configuring the Windsor.
In case you use Castle.MicroKernel.Registration interface, you should load assemblies manually and then register loaded types in the container.
Castle 本身不进行任何程序集加载,它只是依靠融合来根据其默认探测行为定位程序集 - 所以这更像是一个一般的 .Net Framework 问题。
一种方法是处理程序集解析失败并将运行时定向到程序集所在的位置 - 实现此目的的一种方法是覆盖程序集解析(有关详细信息,请参阅msdn),然后编写一些代码来定位和从正确的位置加载适当的程序集。
这显然允许您支持任何类型的目录方案,而不仅仅是二进制子目录(例如,您可以有一个单独的插件目录)。
您可以使用自定义 XmlInterpreter 来初始化您的容器。创建一个继承 XmlInterpreter 的类并将以下覆盖放在该类中: 这个类处理当前执行程序集目录中的所有 *.dll.config,可以很容易地重写它以使用某种递归文件查找。
public override void ProcessResource( Castle.Core.Resource.IResource source, Castle.MicroKernel.IConfigurationStore store )
{
base.ProcessResource( source, store );
var baseDir = Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location );
foreach( var extraConfig in Directory.GetFiles( baseDir, "*.dll.config" ) )
{
try
{
var interpreter = new XmlInterpreter( extraConfig ) { Kernel = Kernel };
interpreter.ProcessResource( interpreter.Source, store );
}
catch(ConfigurationErrorsException)
{
throw;
}
catch( Exception ex )
{
throw new InvalidOperationException( "Failed to load configuration: " + extraConfig, ex );
}
}
}