.NET Web API“插件”程序集

时间:2017-07-16 01:47:00

标签: c# asp.net asp.net-web-api .net-assembly appdomain

  

一遍又一遍地做同样的事情并期待不同的结果    - 精神错乱;也是我目前的心态

我有一种感觉,我只是错过了一些关键细节,或者我做了一些愚蠢的事情(参见 tl; dr

我有一个ASP.NET Web API 2项目,我正在尝试支持“插件”程序集。插件程序集可以/将包含其他Web API控制器和其他类型的任意组合(数据提供程序,业务策略算法等

  • MyProject.Common接口,合同等,由所有引用)
  • MyProject.Core.Api仅引用Common;加载Components程序集
  • MyProject.Components.One也只引用Common
  • MyProject.Components.Two也只引用Common

我正在尝试将插件程序集隔离到plugins目录。现在(测试)构建我正在将组件项目的输出( *.dll )复制到MyProject.Core.Api\plugins

我正在尝试使用神奇的Application_Start()方法加载插件程序集:

var directoryName = this.Server.MapPath("~/plugins");
var directoryInfo = new DirectoryInfo(directoryName);
var assemblySet = directoryInfo.GetFiles("*.dll")
    .Select(fileInfo => Assembly.LoadFrom(fileInfo.FullName))
    .ToList();

现在,我在致电HttpConfiguration.MapHttpAttributeRoutes()之前完成所有这些操作,并考虑默认的IAssembliesResolver服务为DefaultAssembliesResolver,并考虑所有DefaultAssembliesResolver所做的是:

return AppDomain.CurrentDomain.GetAssemblies().ToList();

在任何情况下,都无效,无法找到控制器。

从这里开始,我开始关注Customizing controller discovery in ASP.NET Web API并实施了自定义IAssembliesResolver;相反,我根据博客文章从DefaultAssembliesResolver派生。

这只是开始工作,当我还添加:

<configuration>
  <runtime>
    <assemblyBinding>
      <probing privatePath="bin;plugins" />

但是,我看不到其他类型数据提供商等)。我迭代了实现公共层接口的类型(我在其中一个组件项目中创建了MyTestThingy)并尝试通过Activator.CreateInstance()实例化它并得到{{1而§而不是

§:也许这与多次加载的程序集有关?

我认为我做错了什么,或者是在错误的时间。

我的目标最终是将null文件夹中的所有该死的程序集加载到正在运行的~/plugins中,以便可以解析Web API控制器,因此我可以使用组件实现其他事情。

我知道你不能“卸载程序集”,而是需要卸载AppDomain,所以我希望,如果我需要刷新加载的程序集,我可以使用{{3强制重新加载/刷新下一个请求。

  • 我是否在合适的时间加载了插件程序集?如果我不是,我什么时候该?
  • 我使用正确的装载方法吗?我知道有HttpRuntime.UnloadAppDomain()Assembly.LoadFile()Assembly.LoadFrom(),而且他们使用不同的加载上下文(例如,我正在使用AppDomain
  • 由于LoadFrom()共享IIS应用程序池的生命周期,我还应该考虑其他因素吗?我可以强制回收/重装吗?
  • 我到底做错了什么?
  

tl; dr - 在ASP.NET中没有简单的方法来管理运行时加载的“插件”程序集,特别是使用Web API,这样就可以提取AppDomain类型,什么/其他东西进入主机应用程序?而且,强制应用程序重新加载ApiController,从而重新加载所有插件程序集?

  • 我尝试过修补Assembly.Load(),坦白说它很蹩脚。我得到了它试图完成的任务,但它强加了一些愚蠢的约束(你必须克服API只是为了获得有目的地烘焙的导出类型列表,而不是实例)。
  • MEF是噩梦般的,感觉就像试图用大炮杀死一只苍蝇。另外,我不想在每个AppDomainMAF
  • 之间跳转

0 个答案:

没有答案