简单注入器容器无法从插件外部库注册 Web API 控制器

Simple Injector Container Fails To Register Web API Controller From Pluggedin External Library

这个问题是在容器上调用扩展方法 container.RegisterWebApiControllers(GlobalConfiguration.Configuration) 时发现的,该方法应该向容器注册网络 api 控制器,但没有。请注意,网络 api 控制器在不同的 class 库项目中定义,并在应用程序启动时使用自定义 IAssembliesResolver 类型插入。

public static class SimpleInjectorWebApiInitializer
{
    public static void Initialize()
    {
        var container = new Container();

        GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver),
            new ApiAssemblyResolver());

        InitializeContainer(container);

        container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

        container.Verify();

        GlobalConfiguration.Configuration.DependencyResolver = 
            new SimpleInjectorWebApiDependencyResolver(container);
    }

我什至尝试调用手动获取 ControllerTypes 以使用下面的代码查看发生了什么,但它从未触发 GetAssemblies 方法,也没有 return 任何 ControllerTypes.

var controllerTypes = httpConfigServicesContainer.GetHttpControllerTypeResolver()
    .GetControllerTypes(
        GlobalConfiguration.Configuration.Services.GetAssembliesResolver());

我几乎把头发都拔光了,因为我似乎看不出自己做错了什么。提前感谢您的帮助。

很难说得很具体,但这里列出了可能导致您的控制器未注册的原因:

  • 您的 ApiAssemblyResolver 没有 return 包含控制器的组件。
  • 那个程序集是一个动态程序集(意思是Assembly.IsDynamic returns true)。 Web API 将跳过动态程序集。
  • 控制器类型是内部的。 Web API 仅使用 public 类型。
  • 控制器类型不是 类(而是结构)。
  • 它们的类型名称不以 "Controller"
  • 结尾
  • 他们没有实施 IHttpController
  • 您的 IAssembliesResolver 未正确注册(可能您缺少绑定重定向,导致您的应用程序引用两个版本的 Web API)。提示:检查类型 GlobalConfiguration.Configuration.Services.GetAssembliesResolver() 实际解析的内容。

也可以尝试以下方法:

var controllerTypes = httpConfigServicesContainer.GetHttpControllerTypeResolver()
    .GetControllerTypes(new ApiAssemblyResolver());

这会产生任何控制器吗?在这种情况下,对 Replace(typeof(IAssembliesResolver).

的调用可能会遗漏某些内容

解决方案在于进行配置调用的顺序。我将涉及 IOC 容器的每个配置调用都移到了 Global.asax 文件的 Application_Start 方法中。

在调用 GlobalConfiguration.Configure(WebApiConfig.Register) 之前, 我已经打电话给

GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver), new ApiAssemblyResolver())

替换默认程序集解析器。我终于在每次其他配置调用之后放置了另一个容器 web api 配置设置,它开始像魅力一样工作!即

var apiIOCContainer = new Container();
SimpleInjectorWebApiInitializer.InitializeContainer(apiIOCContainer);
apiIOCContainer.RegisterWebApiControllers(GlobalConfiguration.Configuration);
GlobalConfiguration.Configuration.DependencyResolver =
new SimpleInjectorWebApiDependencyResolver(apiIOCContainer);