C# 从内存加载程序集的简单方法
我有一个应用程序使用一些外部程序集(如htmlAgilityPack等)。 我是否可以从内存(在主代码启动之前)加载此程序集,而无需对应用程序进行复杂修改? 例如,主应用程序从服务器程序集(如字节数组)下载、加载并启动主代码。 如何在不修改应用程序代码的情况下解决此问题 补充说C# 从内存加载程序集的简单方法,c#,.net,.net-assembly,C#,.net,.net Assembly,我有一个应用程序使用一些外部程序集(如htmlAgilityPack等)。 我是否可以从内存(在主代码启动之前)加载此程序集,而无需对应用程序进行复杂修改? 例如,主应用程序从服务器程序集(如字节数组)下载、加载并启动主代码。 如何在不修改应用程序代码的情况下解决此问题 补充说 例如,我使用来自HtmlAlityPack的HtmlDocument。如果im未设置对HtmlAlityPack的引用,则不会编译应用程序。如何在代码中使用Assembly.Load来加载HtmlAgilityPack并
例如,我使用来自HtmlAlityPack的HtmlDocument。如果im未设置对HtmlAlityPack的引用,则不会编译应用程序。如何在代码中使用Assembly.Load来加载HtmlAgilityPack并在应用程序中使用它的类型?以下代码将通过搜索额外文件夹(本例中为PluginsFolder)来处理加载DLL失败的尝试。您可以将其更改为从web服务下载
字节[]
,然后使用适当的方法加载它
注意以下几点:
- 代码应该进入应用程序入口点(例如
方法)Main
- 我们锁定解析过程,因为它可以在不同的线程上调用
- 我们存储以前解析的程序集列表以提高性能
- 如果尝试在ASP.NET中使用此选项,则会出现问题。诸如“它不起作用”之类的问题
//
///存储已解析的程序集的列表。
///
私有IDictionary resolvedAssemblies=新字典();
公共服务1()
{
//注册程序集解析程序以从插件文件夹加载程序集。
//这允许插件使用他们喜欢的任何依赖项。
AppDomain.CurrentDomain.AssemblyResolve+=(发件人,参数)=>
{
锁(此.resolvedAssemblies)
{
如果(!this.resolvedAssemblies.ContainsKey(args.Name))
{
//使用AssemblyName类获取名称
var name=新的AssemblyName(args.name).name;
var file=Path.GetFullPath(Path.Combine(Settings.Default.ParsersFolder,name+“.dll”);
log.Info(“正在尝试加载程序集”+文件);
如果(!File.Exists(File))
{
返回null;
}
var assembly=assembly.LoadFile(文件);
if(assembly.FullName!=args.Name)
{
返回null;
}
resolvedAssemblies.Add(args.Name,assembly);
}
返回此.resolvedAssemblies[args.Name];
}
};
}
请注意,这是针对汇编语言系列而非网络程序集的……您看过方法系列了吗?答案就在这里:)你也可能想看看这个事件-基本上,这个事件在找不到程序集时被触发,然后它会给你一个机会下载程序集,加载它,然后返回它。RB,非常有趣!如果应用程序目录中不存在程序集,我是否可以使用此事件“手动”加载程序集?我已经发布了一些代码,说明如何使用此方法从插件文件夹加载程序集。将其更改为从web服务或其他地方下载字节数组应该很容易。谢谢!我想这就是我所需要的
/// <summary>
/// Stores a list of assemblies we have resolved.
/// </summary>
private IDictionary<string, Assembly> resolvedAssemblies = new Dictionary<string, Assembly>();
public Service1()
{
// Register an assembly resolver to load assemblies from the Plugins folder.
// This allows plugins to use any dependencies they like.
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
lock (this.resolvedAssemblies)
{
if (!this.resolvedAssemblies.ContainsKey(args.Name))
{
//Use the AssemblyName class to get the name
var name = new AssemblyName(args.Name).Name;
var file = Path.GetFullPath(Path.Combine(Settings.Default.ParsersFolder, name + ".dll"));
log.Info("Attempting to load assembly " + file);
if (!File.Exists(file))
{
return null;
}
var assembly = Assembly.LoadFile(file);
if (assembly.FullName != args.Name)
{
return null;
}
resolvedAssemblies.Add(args.Name, assembly);
}
return this.resolvedAssemblies[args.Name];
}
};
}