如何在dotnet core中动态加载程序集

编程入门 行业动态 更新时间:2024-10-27 13:24:23
本文介绍了如何在dotnet core中动态加载程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在构建一个Web应用程序,在这里我需要单独的关注点,即在不同项目中具有抽象和实现。

I'm building a web application, where I would like separate concerns, i.e. having abstractions and implementations in different projects.

为了实现这一点,我尝试了实现组合根概念,其中所有实现都必须具有 ICompositionRootComposer 实例以注册服务,类型等。

To achieve this, I've tried to implement a composition root concept, where all implementation must have an instance of ICompositionRootComposer to register services, types etc.

public interface ICompositionRootComposer { void Compose(ICompositionConfigurator configurator); }

在直接在构建层次结构中引用的项目中, ICompositionRootComposer 被调用,并且服务在基础IoC容器中正确注册。

In projects that are referred directly in the build hierarchy, implementations of ICompositionRootComposer are called, and services are registered correct in the underlying IoC container.

当我尝试注册时会出现问题项目中的服务,我在其中设置了一个后构建任务,该任务将已构建的dll复制到Web项目的调试文件夹中:

The problem arises when I'm trying to register services in a project, where I've set up a post build task that copies the built dll to the web project's debug folder:

cp -R $(TargetDir)"assembly and symbol name"* $(SolutionDir)src/"webproject path"/bin/Debug/netcoreapp1.1

我正在用以下方式加载程序集:(灵感:如何加载位于核心控制台应用程序文件夹中的程序集)

I'm loading the assembly with: (Inspiration: How to load assemblies located in a folder in core console app)

internal class AssemblyLoader : AssemblyLoadContext { private string folderPath; internal AssemblyLoader(string folderPath) { this.folderPath = Path.GetDirectoryName(folderPath); } internal Assembly Load(string filePath) { FileInfo fileInfo = new FileInfo(filePath); AssemblyName assemblyName = new AssemblyName(fileInfo.Name.Replace(fileInfo.Extension, string.Empty)); return this.Load(assemblyName); } protected override Assembly Load(AssemblyName assemblyName) { var dependencyContext = DependencyContext.Default; var ressource = dependencyContext.CompileLibraries.FirstOrDefault(r => r.Name.Contains(assemblyName.Name)); if(ressource != null) { return Assembly.Load(new AssemblyName(ressource.Name)); } var fileInfo = this.LoadFileInfo(assemblyName.Name); if(File.Exists(fileInfo.FullName)) { Assembly assembly = null; if(this.TryGetAssemblyFromAssemblyName(assemblyName, out assembly)) { return assembly; } return this.LoadFromAssemblyPath(fileInfo.FullName); } return Assembly.Load(assemblyName); } private FileInfo LoadFileInfo(string assemblyName) { string fullPath = Path.Combine(this.folderPath, $"{assemblyName}.dll"); return new FileInfo(fullPath); } private bool TryGetAssemblyFromAssemblyName(AssemblyName assemblyName, out Assembly assembly) { try { assembly = Default.LoadFromAssemblyName(assemblyName); return true; } catch { assembly = null; return false; } } }

有了这个加载程序集并调用项目 ICompositionRootComposer 实现。

With this I'm able to load the assembly and call the projects ICompositionRootComposer implementation.

但是问题在于它似乎并没有认识到我的任何类型。

But the problem is that it doesn't seem to recognize any of my types.

使用

configurator.RegisterTransiantService<IFoo, Foo>();

应该在IoC中注册IFoo和Foo。 但是在调试时'无法获取类型的信息,即无法通过Visual Studio Code的调试控制台中的typeof(Foo)获得。

it should register IFoo and Foo in the IoC. But when debugging I'm not able to get info of the types, i.e via typeof(Foo) in the debug console in Visual Studio Code.

推荐答案

我找到了解决问题的方法。

I found a solution to my problem.

原来,我将属性 PreserveCompilationContext 设置为true ,这就是为什么调试器不会注册我手动复制的程序集的原因。 当我从网络项目csproj文件中删除该属性时,一切正常。

It turned out, that I had the property PreserveCompilationContext set to true, and that's why the debugger wouldn't register my manually copied assembly. When I removed the property from the web project csproj file, everything worked.

更多推荐

如何在dotnet core中动态加载程序集

本文发布于:2023-11-14 13:21:36,感谢您对本站的认可!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:加载   程序   动态   如何在   core

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!