Castle Windsor 无法解析 WebApi 中的类型
Castle Windsor cannot resolve type in WebApi
我创建了一个 WebApi 项目并将 Castle Windsor 配置为 DI 容器。
当我在 WebServer 上部署 WebApi 时,一切正常,直到我通过单击重新启动按钮或执行 iisreset
重新启动 Web 服务器(我正在使用 IIS
)命令。在那之后,我总是有以下错误:
No component for supporting the service
XXX.ICategoryDomainService
was found
当 运行 我的项目在 Visual Studio
中处于调试模式时,这个问题似乎是随机发生的。但每次我做一个完整的 Clean/Rebuild
,它至少会工作一次。 Stopping/Starting 项目多次(总是在 Visual Studio
内)将问题带回来。当出现异常时,我检查了 Container 的状态,一切似乎都正常
更新:
好的,我终于找到了问题所在(但我暂时没有合适的解决方案)。
我正在扫描我当前项目的所有类型的框架 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());
一个小的扩展方法(总是在 Framework 中)
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 中注册我的所有 类。然后就可以了。。。但是不是最优的,如果能自动注册就更好了。。。
我觉得你的问题出在行上
ApplicationDomain.Current.ConcreteClasses
简而言之,如果程序集被引用但未在代码中使用,则从应用程序域获取类型是不可靠的。因此,修复将在您的 boostrap 代码中显式引用包含安装程序的程序集,例如:
var t = typeof(BusinessInstaller).Assembly
有关类似问题,请参阅此 post。
我创建了一个 WebApi 项目并将 Castle Windsor 配置为 DI 容器。
当我在 WebServer 上部署 WebApi 时,一切正常,直到我通过单击重新启动按钮或执行 iisreset
重新启动 Web 服务器(我正在使用 IIS
)命令。在那之后,我总是有以下错误:
No component for supporting the service XXX.ICategoryDomainService was found
当 运行 我的项目在 Visual Studio
中处于调试模式时,这个问题似乎是随机发生的。但每次我做一个完整的 Clean/Rebuild
,它至少会工作一次。 Stopping/Starting 项目多次(总是在 Visual Studio
内)将问题带回来。当出现异常时,我检查了 Container 的状态,一切似乎都正常
更新:
好的,我终于找到了问题所在(但我暂时没有合适的解决方案)。
我正在扫描我当前项目的所有类型的框架 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());
一个小的扩展方法(总是在 Framework 中)
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 中注册我的所有 类。然后就可以了。。。但是不是最优的,如果能自动注册就更好了。。。
我觉得你的问题出在行上 ApplicationDomain.Current.ConcreteClasses
简而言之,如果程序集被引用但未在代码中使用,则从应用程序域获取类型是不可靠的。因此,修复将在您的 boostrap 代码中显式引用包含安装程序的程序集,例如:
var t = typeof(BusinessInstaller).Assembly
有关类似问题,请参阅此 post。