从内存加载程序集的简便方法

时间:2014-03-07 09:59:59

标签: c# .net .net-assembly

我有一个应用程序使用一些外部程序集(如htmlAgilityPack等)。 我是否可以从内存中加载此程序集(在主代码启动之前)而无需复杂修改我的应用程序? 例如,从服务器程序集(如字节数组)下载主应用程序,加载它并启动主代码。 如何在不修改应用程序代码的情况下解决它?

加入。

例如,我使用HtmlAgilityPack中的HtmlDocument。如果我没有设置HtmlAgilityPack应用程序的引用将不会被编译。如何在我的代码中使用Assembly.Load来加载HtmlAgilityPack并在应用程序中使用它?

1 个答案:

答案 0 :(得分:1)

以下代码将处理通过搜索额外文件夹(在本例中为PluginsFolder)加载DLL失败的尝试。您可以更改它以从Web服务下载Byte[],然后使用适当的Assembly.Load方法加载它。

请注意以下几点:

  • 代码应该放在您的应用程序入口点(例如您的Main方法)。
  • 我们锁定解析程序,因为它可以在不同的线程上调用。
  • 我们存储先前已解析的程序集列表以提高性能。
  • 如果您尝试在ASP.NET中使用此功能,则会出现问题。类似的问题"它不起作用"。

代码:

/// <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];
        }
    };
}