gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 17:42:59 25 4
gpt4 key购买 nike

我正在构建一个 Web 应用程序,我希望在其中有不同的关注点,即在不同的项目中具有抽象和实现。

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

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

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

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

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

我正在加载程序集:(灵感:How to load assemblies located in a folder in .net 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 实现。

但问题是它似乎无法识别我的任何类型。

当调用我的配置器时

configurator.RegisterTransiantService<IFoo, Foo>();

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

最佳答案

死灵法术。


您可以为旧的 Assembly.LoadFile 创建一个包装类来执行此操作。

这还有一个额外的好处,即您可以通过在旧代码库中应用搜索和替换更改来保持与 dotnet-none-core 的向后兼容。

namespace System.Reflection
{
public class Assembly2
{
public static System.Reflection.Assembly LoadFile(string path)
{
System.Reflection.Assembly assembly = null;

#if NET_CORE
// Requires nuget - System.Runtime.Loader
assembly = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
#else
assembly = System.Reflection. Assembly.LoadFile(path);
#endif
return assembly;
}
}
}

您需要通过 NuGet 添加 System.Runtime.Loader

关于c# - 如何在 dotnet core 中动态加载程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43353999/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com