【问题标题】:Assembly resolving in ASP.NET project outside of bin folder在 bin 文件夹之外的 ASP.NET 项目中解析程序集
【发布时间】:2013-05-31 22:47:22
【问题描述】:

如何在 ASP.NET Web 开发服务器的 bin 文件夹之外解析程序集引用?这对于没有相同 dll 的副本很有用。

什么都不起作用: probing element at web.config 不起作用,我无法设置域,因为它执行应用程序管理器,我无法订阅 resolve assembly event ,因为为时已晚- 当我可以订阅初始化结束。那我该怎么办?

【问题讨论】:

  • 只是好奇 - 你为什么要费尽心思才获得对程序集的引用(与直接/标准的方式只是添加引用)?
  • 如果我理解你的问题,- 因为我们需要明确告诉编译器在编译过程中应该使用哪些程序集。在常见的情况下,它是 Web 项目的引用,但并非总是如此,这就是为什么编译器会等待我们的列表,而不是自己做。您可以简单地测试和添加“Web.Project.Assembly”项目,在大多数情况下会出现初始化错误。
  • 嗯..引用它(在开发早期)和出错(在构建期间假设)与在其他时间点告诉编译器“合并”它有什么区别您的应用程序(我假设会在开发后期产生相同的错误+)?我完全出于好奇而问 - 希望你不介意(如你所知,我没有/没有按照你的方式做事 - 还没有找到理由)。
  • 我可以告诉你我为什么需要这种方法。因为现在我们在前端和后端项目中有很多相同的 dll 副本。处理这个问题的方法 - 从公共 bin 文件夹中加载 dll。这是我发现的唯一一个记录不充分的方式。
  • 我不太懂asp.net编译器。它没有很好的记录。我知道程序集加载和解析是在初始化步骤中完成的。正如我所见,ASP.NET 编译器不会解析 JIT 编译器等引用的程序集。它认为所有引用的程序集都必须在同一个文件夹中,并且他只是返回初始化错误而没有引发程序集解析事件。但是,如果我们使用 BuildManager.AddReferencedAssembly 将程序集添加到依赖程序集列表中,他将搜索它并正常引发程序集解析事件。这是更多的经验知识。

标签: asp.net .net reflection webserver .net-assembly


【解决方案1】:

我们可以使用PreApplicationStartMethodAttribute 并标记它们一些不带参数的公共静态 void 方法(在 web 项目程序集中)。这可以在 AssemblyInfo.cs 类中完成 例如:

[assembly: PreApplicationStartMethod(
  typeof(Web.Initializer), "Initialize")]

该方法将在编译之前但在处理 web.config 之后调用。所以我们必须明确告诉编译器它需要在编译期间使用的程序集。此外,我们需要在这里订阅 Assembly Resolve 事件,以便我们可以管理程序集解析。示例如下:

  public static class Initializer
    {
        public static void Initialize()
        {
            AppDomain.CurrentDomain.AssemblyResolve += LoadFromCommonBinFolder;
            var referAsm = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
            foreach (var assemblyName in referAsm)
            {
               try
               {
                var curAsm = Assembly.Load(assemblyName);
                BuildManager.AddReferencedAssembly(curAsm);
                LoadChildReferences(curAsm);
               }
               catch {}
            }
        }

    private static void LoadChildReferences(Assembly curAsm)
    {
       foreach (var assemblyName in curAsm.GetReferencedAssemblies())
       {
           try
           {
             BuildManager.AddReferencedAssembly(Assembly.Load(assemblyName));
           }
           catch {}
       }
    }

        private static Assembly LoadFromCommonBinFolder(object sender, ResolveEventArgs args)
        {
            string commonBinFolder = System.Configuration.ConfigurationManager.AppSettings["CommonBinFolderPath"];

            if (String.IsNullOrEmpty(commonBinFolder))
            {
                throw new InvalidOperationException("​​CommonBinFolderPath in the app.config isn't seted.");
            }

            string assemblyName = new AssemblyName(args.Name).Name;
            string assemblyPath = Path.Combine(commonBinFolder, assemblyName);

            if (!File.Exists(assemblyPath + ".dll"))
            {
                if (!File.Exists(assemblyPath + ".exe"))
                {
                    //searching for resources
                    var ci = CultureInfo.CurrentUICulture;
                    assemblyPath = Path.Combine(commonBinFolder, ci.Name, assemblyName + ".dll");
                    if (!File.Exists(assemblyPath))
                    {
                        assemblyPath = Path.Combine(commonBinFolder, ci.Parent, assemblyName + ".dll");
                        if (!File.Exists(assemblyPath))
                        {
                            return null;
                        }
                    }
                }
            }

            return Assembly.LoadFrom(assemblyPath);
        }
    }

在这种情况下,“Web.Project.Assembly”仍然必须位于 bin 文件夹中。其他程序集可以从任何文件夹共享。

web.config 文件中编译元素下包含的程序集也必须位于 bin 文件夹或设置了探测元素的子文件夹中。

在同样的情况下,我们还必须在此代码中添加对子程序集的引用。

【讨论】:

    【解决方案2】:

    为什么使用“BuildManager.AddReferencedAssembly”?

    在 'Application_Start' 方法中绑定事件 'AssemblyResolve' 并在 aspx 页面中使用程序集名称设置 Inherits,没有 'BuildManager.AddReferencedAssembly'。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      相关资源
      最近更新 更多