自托管 WebAPI 应用程序引用来自不同程序集的控制器
Posted
技术标签:
【中文标题】自托管 WebAPI 应用程序引用来自不同程序集的控制器【英文标题】:Self-hosting WebAPI application referencing controller from different assembly 【发布时间】:2012-06-14 20:50:28 【问题描述】:我遇到了this gem,它似乎与我想要的很接近。但是,我想使用引用程序集中已经编写好的控制器。
我的第一次破解是引用程序集,设置路由规则和原来的webAPI项目一样去,但是每次尝试调用自托管服务都会得到400s。我已经通过 Fiddler 挑选了请求的内容,除了地址差异之外,针对 webAPI 项目和自托管项目的请求是相同的。
我觉得这应该是相对简单的,但我还没有找到一个可以接受的答案。
【问题讨论】:
既然 OP 已经明确放弃了这个问题,有没有其他人确认过任何一个提议的解决方案? 没有放弃,我从来没有用有问题的 WebAPI 版本解决问题。 我刚刚验证了@cypressx 提出的建议,它按描述工作。谢谢。 【参考方案1】:这似乎是一个已知问题。您必须强制 .NET 使用您需要的控制器加载程序集。
在您自行托管 Web API 之前,您应该从参考程序集中检索您希望由运行时加载的类型。像这样的:
Type controllerType = typeof(ReferencedControllers.ControllerType);
这应该从这个程序集中加载控制器,它不会给你 404 错误。
【讨论】:
我已经确认这是正确的信息。我的步骤:(1)创建新的 MVC4 项目,(2)创建新的类库项目,(3)将 MVC4 WebAPI NuGet 包添加到类库项目(4)从 Web 项目引用类库(5)将 Web API 控制器添加到类库项目 (5) 修改Application_Start
与上面建议的代码类似的行。我能够导航到类库项目中定义的 webapi 控制器,所有请求都按预期运行。
似乎适用于当前版本的 WebAPI。谢谢,肖恩!
请注意,那一行:Type controllerType = typeof(ReferencedControllers.ControllerType);仅适用于调试模式,发布时优化忽略它..
您可以做的另一件事是在自托管它的 .exe 项目中添加对 web api dll 的引用。如果你不引用它,它可能不会被复制到运行时文件夹中。
简单地引用类型依赖于 DefaultAssembliesResolver 来完成工作。 Eric Boumendil 的回答确保程序集被正确加载,并且不会被编译器意外优化掉......【参考方案2】:
link 为同样的问题节省了我的时间 :)...
我只需要更改以下语句以适应 selfhost webapi 配置。
GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver());
与
var config = new HttpSelfHostConfiguration("http://localhost:8081");
config.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver());
【讨论】:
这个链接节省了一天.....我有MS“简单示例”,没有任何分层。谢谢!【参考方案3】:Praveen 和 Janushirsha 以前的帖子引导我走向正确的方向,我在这里继续:
// Not reliable in Release mode :
Type controllerType = typeof(ReferencedControllers.ControllerType);
因此,您应该将IAssembliesResolver
替换为:
HttpConfiguration config = new HttpConfiguration();
config.Services.Replace(typeof(IAssembliesResolver), new CustomAssembliesResolver());
这是CustomAssembliesResolver
的实现示例
using System.Web.Http.Dispatcher;
internal class CustomAssembliesResolver : DefaultAssembliesResolver
public override ICollection<System.Reflection.Assembly> GetAssemblies()
var assemblies = base.GetAssemblies();
// Interestingly, if we push the same assembly twice in the collection,
// an InvalidOperationException suggests that there is different
// controllers of the same name (I think it's a bug of WebApi 2.1).
var customControllersAssembly = typeof(AnotherReferencedAssembly.MyValuesController).Assembly;
if (!assemblies.Contains(customControllersAssembly))
assemblies.Add(customControllersAssembly);
return assemblies;
如果未引用第三方程序集或您想要后期程序集绑定,则可以轻松修改此代码。
希望对您有所帮助。
【讨论】:
这帮助很大。谢谢!我认为这应该是公认的答案。 感谢您的评论。很高兴为您提供帮助。 我很难理解你的例子。我正在制作一个启动 webApi 服务的组件。我想从外部应用程序将控制器注入其中。这可能吗?它似乎只是在它自己的项目中神奇地找到了控制器? (我不确定它是如何与这些绑定的……某种幕后反射魔法) 如果我理解您想要达到的目标,答案是肯定的,这是可能的。如果您像示例中那样设置了 IAssembliesResolver,它应该能够解析来自另一个程序集的控制器。 我在这里遇到了类似的问题:***.com/questions/48652339/…,我的 CustomAssembliesResolver 没有被调用。以上是关于自托管 WebAPI 应用程序引用来自不同程序集的控制器的主要内容,如果未能解决你的问题,请参考以下文章
如何在本地服务结构集群中部署和访问来宾可执行文件(ASP.NET OWIN 自托管 webapi 应用程序)