在ASP.NET 5中动态加载程序集

我曾经有一些代码扫描了我的应用程序的bin目录中的程序集,这些程序集尚未加载到AppDomain中并加载它们。 它基本上看起来像:

 foreach (var assemblyPath in Directory.GetFiles("path\to\bin", "*.dll")) { var inspected = Assembly.ReflectionOnlyLoadFrom(assemblyPath); Assembly.Load(inspected.GetName()); } 

为简洁起见,我跳过了try / catch子句等。

这允许我在运行时删除bin文件夹中的程序集以及某些接口的实现,并让IoC容器自动拾取它们。 现在使用新的Roslyn魔法,在调试时不再有物理DLL了。 有没有办法动态检索程序集名称,项目名称或依赖项名称(在project.json )。

我想我必须在Entropy repo中实现类似这个例子的东西,但我不知道如何为我的场景实现它。

您正在寻找的是ILibraryManager实现,它提供对应用程序的完整依赖关系图的访问。 这已经流过ASP.NET 5 DI系统了。 所以,你可以从那里接触它。

可以在RoslynCompilationService找到示例用法 。

您可以使用IAssemblyLoadContextAccessor接口动态加载ASP.NET 5类库(.xproj)项目。 以下示例代码适用于Beta 4:

 public class Startup { public void Configure(IApplicationBuilder app) { var assemblyLoadContextAccessor = app.ApplicationServices.GetService(); var loadContext = assemblyLoadContextAccessor.Default; var loadedAssembly = loadContext.Load("NameOfYourLibrary"); } } 

我解决了这个问题,部分使用ILibraryManager建议的ILibraryManager。 我稍微改变了方法,因此无需扫描bin文件夹以获取新程序集。 我只想要当前AppDomain中所有已加载的程序集。

我在我的类型查找器类中注入了一个ILibraryManager接口的实例,并使用了GetReferencingLibraries()方法和核心程序集的名称,该程序集由应用程序中的所有其他程序集引用。

可以在此处找到示例实现,其中这是重要的部分:

 public IEnumerable GetLoadedAssemblies() { return _libraryManager.GetReferencingLibraries(_coreAssemblyName.Name) .SelectMany(info => info.Assemblies) .Select(info => Assembly.Load(new AssemblyName(info.Name))); } 

对于.net核心用户,这是我从特定路径加载程序集的代码。 我不得不使用指令,因为它与.Net Framework和.Net Core略有不同。

在您的类标题中,您需要声明使用类似于:

 #if NET46 #else using System.Runtime.Loader; #endif 

在您的函数中类似于以下内容:

 string assemblyPath = "c:\temp\assmebly.dll"; #if NET46 Assembly assembly = Assembly.LoadFrom(assemblyPath); #else AssemblyLoadContext context = AssemblyLoadContext.Default; Assembly assembly = context.LoadFromAssemblyPath(assemblyPath); #endif