我曾经有一些代码扫描了我的应用程序的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
中)。
我想我必须实现像this example in the Entropy repo之类的东西,但我不知道如何为我的场景实现它。
答案 0 :(得分:6)
您可以使用IAssemblyLoadContextAccessor
接口动态加载ASP.NET 5类库(.xproj)项目。以下示例代码适用于Beta 4:
public class Startup
{
public void Configure(IApplicationBuilder app)
{
var assemblyLoadContextAccessor = app.ApplicationServices.GetService<IAssemblyLoadContextAccessor>();
var loadContext = assemblyLoadContextAccessor.Default;
var loadedAssembly = loadContext.Load("NameOfYourLibrary");
}
}
答案 1 :(得分:2)
您正在寻找的是ILibraryManager
实现,它提供了对应用程序的完整依赖关系图的访问。这已经流过ASP.NET 5 DI系统了。所以,你可以从那里接触它。
答案 2 :(得分:1)
我使用@tugberk建议的ILibraryManager
部分解决了这个问题。我稍微改变了方法,因此无需为新程序集扫描bin
文件夹。我只想要当前AppDomain中所有已加载的程序集。
我在类型查找器类中注入了ILibraryManager
接口的实例,并使用GetReferencingLibraries()
方法和核心程序集的名称,该程序集由应用程序中的所有其他程序集引用。 / p>
可以找到示例实现here,其中这是重要的部分:
public IEnumerable<Assembly> GetLoadedAssemblies()
{
return _libraryManager.GetReferencingLibraries(_coreAssemblyName.Name)
.SelectMany(info => info.Assemblies)
.Select(info => Assembly.Load(new AssemblyName(info.Name)));
}
答案 3 :(得分:0)
对于.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
答案 4 :(得分:0)
它不是ASP.NET,但可以轻松转换为asp.net。 在用于加载程序集的if函数下方,并在该程序集的类内调用方法。
private static FormCustomized loadLayout(global::System.String layoutFilename, global::System.String layoutNameSpace)
{
FormCustomized mainForm = default;
Type typeMainLayout = default;
FileInfo layoutFile;
layoutFile = new FileInfo(layoutFilename);
layoutFile.Refresh();
if (!layoutFile.Exists)
{
MessageBox.Show("Layout file not found. You need to reinstall the program");
return default;
}
try
{
Assembly assemblyRaw = Assembly.LoadFrom(layoutFilename);
AssemblyLoadContext context = AssemblyLoadContext.Default;
Assembly assembly = context.LoadFromAssemblyPath(layoutFilename);
Type typeMainLayoutIni = assembly.GetType(layoutNameSpace + ".initializeLayoutClass");
Object iniClass = Activator.CreateInstance(typeMainLayoutIni, true);
MethodInfo methodInfo = typeMainLayoutIni.GetMethod("AssembliesToLoadAtStart");
enVars.assemblies = (Dictionary<string, Environment.environmentAssembliesClass>)methodInfo.Invoke(iniClass, default);
typeMainLayout = assembly.GetType(layoutNameSpace + ".mainAppLayoutForm");
mainForm = Activator.CreateInstance(typeMainLayout, enVars) as FormCustomized;
}
catch (Exception ex)
{
return default;
}
return default;
}