【问题标题】:Castle Windsor cannot resolve type in WebApiCastle Windsor 无法解析 WebApi 中的类型
【发布时间】:2015-07-19 16:06:43
【问题描述】:

我创建了一个 WebApi 项目并将 Castle Windsor 配置为 DI 容器。

当我在 WebServer 上部署 WebApi 时,一切正常,直到我通过单击重新启动按钮或执行 iisreset 命令重新启动 Web 服务器(我正在使用 IIS)。之后,我总是出现以下错误:

没有支持服务的组件 XXX.ICategoryDomainService 找到了

当在Visual Studio 中以调试模式运行我的项目时,这个问题似乎是随机发生的。但每次我做一个完整的Clean/Rebuild,它至少工作一次。多次停止/启动项目(总是在Visual Studio 内)会使问题再次出现。当引发异常时,我检查了 Container 的状态,一切似乎都正常

更新:

好的,我终于找到了问题所在(但我目前没有合适的解决方案)。
我正在一个框架 dll 中进行注册,该 dll 会扫描我当前项目的所有类型,然后尝试自动注册其中一些类型...

在框架库中:

IEnumerable<IInstaller> installers = this.Container.ResolveAll<IInstaller>();
foreach (IInstaller installer in installers)
{
    installer.Install(this.Container);
}

IInstaller 是这样注册的:

this.Container.Register(Classes
    .From(ApplicationDomain.Current.ConcreteClasses)
    .BasedOn<IInstaller>()
    .WithServiceAllInterfaces()
    .LifestylePerWebRequest());

一个小的扩展方法(总是在框架中)

public static void RegisterAllServices(this IWindsorContainer container, 
    IEnumerable<Type> types)
{
    container.Register(Classes
        .From(types)
        .BasedOn<IService>()
        .WithServiceAllInterfaces()
        .LifestyleTransient());
}

我项目中的安装程序

public class BusinessInstaller : IInstaller
{
    public void Install(IWindsorContainer container)
    {
        Type[] types = typeof(BusinessInstaller).Assembly.GetTypes();
        container.RegisterAllServices(types);
    }
}

这很奇怪,但这是我可以观察到的:扩展方法 RegisterAllServices 仅在我进行完全重建时才被调用。之后,在调试模式下,我可以看到调试器只是跳过了从未进入此方法的步骤,但无论如何都注册了类型(但可能是以错误的方式,因为 Windsor 无法解析它们!)。

临时解决方法是在 BusinessInstaller 中注册我的所有类。然后就可以了……不过不是最优的,要是能自动注册就更好了……

【问题讨论】:

  • 您的注册情况如何?以及IDependecyResolver的耦合城堡在哪里?
  • 我没有看到任何特别的东西。但是我问自己是否有办法重新初始化Container.Current....在我以前的工作中,我是使用WebApi 配置城堡的人,我相信我遗漏了一些东西...我需要找到我的POC,找到了就上传……还有一件事,我觉得你应该上传ICategoryDomainService的注册。
  • 您的 Container 类依赖静态构造函数来初始化 WindsorContainer。以我的经验,这在 ASP.NET 中运行时令人担忧。您的代码应保证每次调用 Application_Start() 时都会实例化并配置容器。另外,为什么要在 Container() 静态构造函数和 ContainerConfiguration.Configure() 之间拆分容器的初始化?
  • 我从静态构造函数中删除了初始化并将其放入属性中(对SingletonContainer 进行了空检查),但它没有帮助。将这两者分开的原因是我的Container 级别很低(它隐藏在框架库中的某个地方),我不想引用整个 WebApi 的东西,比如IDependencyResolverApiControllerInstaller跨度>

标签: c# .net dependency-injection castle-windsor asp.net-web-api


【解决方案1】:

我认为你的问题在于 ApplicationDomain.Current.ConcreteClasses

简而言之,如果程序集被引用但未在代码中使用,则从应用程序域获取类型是不可靠的。因此,修复将在您的引导代码中明确引用包含安装程序的程序集,例如:

var t = typeof(BusinessInstaller).Assembly

查看此post 了解类似问题。

【讨论】:

  • 天哪!我搜索了这么多小时问题是什么...我不明白为什么没有引发明确的异常...谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-26
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多