如何在ASP.NET Web开发服务器的bin文件夹之外解析程序集引用?这对于没有相同dll的副本非常有用。
没有任何效果: probing element at web.config不起作用,我无法设置域名,因为它执行应用程序管理器,我无法订阅resolve assembly event 因为它太晚了 - 当我可以订阅初始化结束了。那我该怎么办?
答案 0 :(得分:5)
我们可以使用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文件夹中或设置了探测元素的子文件夹中。
在同样的情况下,我们还必须在此代码中添加对子程序集的引用。
答案 1 :(得分:0)
为什么要使用'BuildManager.AddReferencedAssembly'?
在'Application_Start'方法中绑定事件'AssemblyResolve'并在aspx页面中设置Inherits with assembly name,没有'BuildManager.AddReferencedAssembly'。