这是我的问题。我想在运行时将库加载到我的应用程序中。这将允许应用程序使用接口的新实现而无需重新编译。应用程序将在其自己的目录中搜索库。我有代码可以达到这个目的:
var path = Assembly.GetExecutingAssembly().Location;
path = Path.GetDirectoryName(path);
path = Path.Combine(path, "<my assembly>.dll");
var assembly = Assembly.LoadFile(path);
此代码在单元测试中完美运行。但是,该应用程序是一个Web应用程序。当我将此代码作为应用程序的一部分运行时,Assembly.GetExecutingAssembly().Location
将返回.net框架内的临时目录。 (C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Temporary ASP.NET Files \ ...)我可以通过使用Server.MapPath
解决这个问题,但是代码将不再是单元可测试的
我真的很想找到能够以平台无关的方式给我执行目录的东西,也就是说,它会在单元测试和Web应用程序中搜索正确的目录。
我试过了:
Assembly.GetExecutingAssembly().Location //Works as a test but not on a server
Application.ExecutablePath //Not an executable, so this won't work
System.AppDomain.CurrentDomain.BaseDirectory //Almost works in web app, but stops too early in the directory structure
Environment.CurrentDirectory //returns system32 directory
答案 0 :(得分:1)
这是我在测试环境和Web应用程序中使用的:
private static string AssemblyDirectory
{
get
{
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
var uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
}
答案 1 :(得分:0)
您可以使用此类方法。它将返回装配的真实位置。
public static string GetAssemblyLocation(Assembly assembly)
{
if (assembly.IsDynamic)
{
return null;
}
string codeBase = assembly.CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
path = Path.GetDirectoryName(path);
path += "\\" + Path.GetFileName(assembly.Location);
return path;
}
CodeBase将返回程序集的原始位置。在Web应用程序的情况下,当所有程序集在Temporary文件夹中使用卷影副本时,CodeBase仍将返回Bin文件夹中的路径。但是使用协议,比如这个文件:// c:/somesite/bin/someassembly.dll。所以这个方法只是得到它并将其转换为通常的文件路径。