程序集解析在bin文件夹之外的ASP.NET项目中

Bra*_* Ds 1 .net asp.net reflection webserver .net-assembly

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

没有什么工作: web.config中的探测元素不起作用,我无法设置域,因为它执行应用程序管理器,我无法订阅解决汇编事件,因为它太晚了 - 当我可以订阅初始化时过度.那我该怎么办?

Bra*_* Ds 6

我们可以使用PreApplicationStartMethodAttribute 并将它们标记为一些没有参数的public static void方法(在web项目程序集中).这可以在AssemblyInfo.cs类中完成例如:

[assembly: PreApplicationStartMethod(
  typeof(Web.Initializer), "Initialize")]
Run Code Online (Sandbox Code Playgroud)

该方法将在编译之前调用,但在处理完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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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