2

更新:我没有提到,我使用的是 Castle 版本 2.5.1.0(有许多依赖项意味着我们没有使用更新的东西)

我一直在使用许多利用 Castle Windsor 的框架,并且很幸运。在某些情况下,由于缺少一些参考,我遇到了尝试从 AppConfig 安装时遇到异常的情况。据我所知,当我执行container.Install(Configuration.FromAppConfig());Castle 之类的操作时,会加载配置文件中注册的所有组件。从每个包含已注册组件的程序集中,我相信 Castle 将检查该程序集的清单,然后加载这些程序集,并以这种方式继续,直到加载所有必需的程序集。

这导致了我遇到的问题。我使用单元测试编写了一些代码。代码使用 Configuration.FromAppConfig() 方法加载多个组件。然后在需要时按名称解析组件。单元测试工作正常。当我在 MVC 控制器中调用此代码时,我开始在调用 Configuration.FromAppConfig() 时遇到错误。这是一些示例代码:

这是一个简化版本,但说明了问题:

public interface IAuthorizer2
{
    string Url { get; set; }
}

public class Foo : IAuthorizer2
{
    public string Url { get; set; }
}

这是 web.config 中的组件:

  <component id="MessageManagerAdmins" service="MsmqManager.Areas.MessageManager.Controllers.IAuthorizer2"
type="MsmqManager.Areas.MessageManager.Controllers.Foo"/>

在我的控制器操作中,我调用:

var container = new WindsorContainer();
container.Install(Configuration.FromAppConfig());

我得到以下异常:(为了完整起见,我将整个内容包括在内)

    Could not load file or assembly 'Spatial4n.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f9456e1ca16d45e' or one of its dependencies. The system cannot find the file specified.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.IO.FileNotFoundException: Could not load file or assembly 'Spatial4n.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f9456e1ca16d45e' or one of its dependencies. The system cannot find the file specified.

Source Error: 


Line 100:        {
Line 101:            var container = new WindsorContainer();
Line 102:            container.Install(Configuration.FromAppConfig());

Source File: c:\Prj\AA\Source\Development\Web\MessageManager\Source\MessageManager\Areas\MessageManager\Controllers\MessageController.cs    Line: 102 

Assembly Load Trace: The following information can be helpful to determine why the assembly 'Spatial4n.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f9456e1ca16d45e' could not be loaded.


=== Pre-bind state information ===
LOG: User = ARCHSTONE\tstappaa
LOG: DisplayName = Spatial4n.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f9456e1ca16d45e
 (Fully-specified)
LOG: Appbase = file:///C:/Prj/AA/Source/Development/Web/AssociatePortal/Source/AssociatePortal/
LOG: Initial PrivatePath = C:\Prj\AA\Source\Development\Web\AssociatePortal\Source\AssociatePortal\bin
Calling assembly : Lucene.Net.Contrib.Spatial, Version=2.9.1.2, Culture=neutral, PublicKeyToken=85089178b9ac3181.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Prj\AA\Source\Development\Web\AssociatePortal\Source\AssociatePortal\web.config
LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet.config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Spatial4n.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f9456e1ca16d45e
LOG: The same bind was seen before, and was failed with hr = 0x80070002.

它正在寻找 Spatial4n.Core 程序集。我以前从未听说过这个大会。我将其追溯到:该站点使用 RavenDB Raven.Database 程序集引用 Spatial4n.Core。

我可以理解为什么 Castle 会尝试解析由于解析组件而可能调用的所有程序集。但是,如果您查看我正在使用的接口/类的定义,这里没有任何依赖关系。我知道我可以下载 Spatial4n.Core 程序集的副本,以及所需的所有其他程序集,但我想了解如何正确配置容器以避免此问题。

我的问题:

  • 有没有更好的方法来填充容器/注册组件,以便我可以按类型和名称解析它们(即 container.Resolve("componentName"))
  • 有没有办法告诉 Castle 不要解决所有可能的程序集引用?
  • 我在城堡项目网站和其他地方做了很多搜索。我还没有找到任何有关 Castle 如何解析这些程序集引用的信息。它主要是关于配置容器的更基本的功能。您能否推荐更深入的文档,我可以在其中了解更多信息?

谢谢。

4

1 回答 1

1

这不完全是 Windsor 的行为,而是 System.Reflection。加载程序集时,不会加载依赖项,但是由于您使用的是“AllTypes”,这意味着将加载包括私有类型在内的每个类型(通过反射),并提示加载程序解决依赖项。

避免这种情况的方法是使用显式注册 Component.For<> 等...

WRT 按名称解析,默认使用完整的类型名称作为键(命名空间+类型名称)

文档薄弱,但源代码并不太复杂。还有很多博客文章。

高温高压

于 2012-10-31T05:05:03.753 回答