현재로드 된 어셈블리를 어떻게 반복합니까?
ASP.NET 응용 프로그램에 데이터베이스 연결 확인, 현재 appSettings 및 ConnectionStrings 표시 등의 작업을 수행하는 "진단"페이지가 있습니다.이 페이지의 섹션에는 전체적으로 사용되는 중요한 유형의 어셈블리 버전이 표시됩니다. 그러나로드 된 모든 어셈블리의 버전을 효과적으로 표시하는 방법을 알 수 없었습니다.
.NET 응용 프로그램에서 현재 참조되거나로드 된 모든 어셈블리 를 파악하는 가장 효과적인 방법은 무엇입니까 ?
참고 : 특정 디렉토리에서 * .dll을 반복하는 것과 같은 파일 기반 방법에는 관심이 없습니다. 현재 응용 프로그램이 실제로 사용 하는 것에 관심이 있습니다.
이 확장 방법은 중첩 된 어셈블리를 포함하여 모든 참조 된 어셈블리를 재귀 적으로 가져옵니다.
는를 사용하므로 ReflectionOnlyLoad
별도의 AppDomain에 어셈블리를로드하므로 JIT 프로세스를 방해하지 않는 이점이 있습니다.
당신은 또한 있음을 알 수 있습니다 MyGetMissingAssembliesRecursive
. 이를 사용하여 참조되었지만 현재 디렉토리에없는 누락 된 어셈블리를 감지 할 수 있습니다. 이것은 MEF를 사용할 때 매우 유용합니다 . 반환 목록은 누락 된 어셈블리와 해당 어셈블리를 소유 한 사람 (부모)을 모두 제공합니다.
/// <summary>
/// Intent: Get referenced assemblies, either recursively or flat. Not thread safe, if running in a multi
/// threaded environment must use locks.
/// </summary>
public static class GetReferencedAssemblies
{
static void Demo()
{
var referencedAssemblies = Assembly.GetEntryAssembly().MyGetReferencedAssembliesRecursive();
var missingAssemblies = Assembly.GetEntryAssembly().MyGetMissingAssembliesRecursive();
// Can use this within a class.
//var referencedAssemblies = this.MyGetReferencedAssembliesRecursive();
}
public class MissingAssembly
{
public MissingAssembly(string missingAssemblyName, string missingAssemblyNameParent)
{
MissingAssemblyName = missingAssemblyName;
MissingAssemblyNameParent = missingAssemblyNameParent;
}
public string MissingAssemblyName { get; set; }
public string MissingAssemblyNameParent { get; set; }
}
private static Dictionary<string, Assembly> _dependentAssemblyList;
private static List<MissingAssembly> _missingAssemblyList;
/// <summary>
/// Intent: Get assemblies referenced by entry assembly. Not recursive.
/// </summary>
public static List<string> MyGetReferencedAssembliesFlat(this Type type)
{
var results = type.Assembly.GetReferencedAssemblies();
return results.Select(o => o.FullName).OrderBy(o => o).ToList();
}
/// <summary>
/// Intent: Get assemblies currently dependent on entry assembly. Recursive.
/// </summary>
public static Dictionary<string, Assembly> MyGetReferencedAssembliesRecursive(this Assembly assembly)
{
_dependentAssemblyList = new Dictionary<string, Assembly>();
_missingAssemblyList = new List<MissingAssembly>();
InternalGetDependentAssembliesRecursive(assembly);
// Only include assemblies that we wrote ourselves (ignore ones from GAC).
var keysToRemove = _dependentAssemblyList.Values.Where(
o => o.GlobalAssemblyCache == true).ToList();
foreach (var k in keysToRemove)
{
_dependentAssemblyList.Remove(k.FullName.MyToName());
}
return _dependentAssemblyList;
}
/// <summary>
/// Intent: Get missing assemblies.
/// </summary>
public static List<MissingAssembly> MyGetMissingAssembliesRecursive(this Assembly assembly)
{
_dependentAssemblyList = new Dictionary<string, Assembly>();
_missingAssemblyList = new List<MissingAssembly>();
InternalGetDependentAssembliesRecursive(assembly);
return _missingAssemblyList;
}
/// <summary>
/// Intent: Internal recursive class to get all dependent assemblies, and all dependent assemblies of
/// dependent assemblies, etc.
/// </summary>
private static void InternalGetDependentAssembliesRecursive(Assembly assembly)
{
// Load assemblies with newest versions first. Omitting the ordering results in false positives on
// _missingAssemblyList.
var referencedAssemblies = assembly.GetReferencedAssemblies()
.OrderByDescending(o => o.Version);
foreach (var r in referencedAssemblies)
{
if (String.IsNullOrEmpty(assembly.FullName))
{
continue;
}
if (_dependentAssemblyList.ContainsKey(r.FullName.MyToName()) == false)
{
try
{
var a = Assembly.ReflectionOnlyLoad(r.FullName);
_dependentAssemblyList[a.FullName.MyToName()] = a;
InternalGetDependentAssembliesRecursive(a);
}
catch (Exception ex)
{
_missingAssemblyList.Add(new MissingAssembly(r.FullName.Split(',')[0], assembly.FullName.MyToName()));
}
}
}
}
private static string MyToName(this string fullName)
{
return fullName.Split(',')[0];
}
}
최신 정보
이 코드 스레드를 안전하게하려면 lock
주위에 두십시오. 마법을 수행하기 위해 공유 정적 전역 변수를 참조하기 때문에 현재 기본적으로 스레드 안전하지 않습니다.
현재의로드 된 어셈블리 가져 오기 AppDomain
:
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
Getting the assemblies referenced by another assembly:
var referencedAssemblies = someAssembly.GetReferencedAssemblies();
Note that if assembly A references assembly B and assembly A is loaded, that does not imply that assembly B is also loaded. Assembly B will only be loaded if and when it is needed. For that reason, GetReferencedAssemblies()
returns AssemblyName
instances rather than Assembly
instances.
참고URL : https://stackoverflow.com/questions/383686/how-do-you-loop-through-currently-loaded-assemblies
'Programing' 카테고리의 다른 글
CSS 또는 Javascript를 사용하여 웹 페이지에서 커서를 숨길 수 있습니까? (0) | 2020.07.17 |
---|---|
쿠키를 서버 측에서 삭제하는 올바른 방법 (0) | 2020.07.17 |
이름을 모르는 경우 Javascript 객체의 속성에 어떻게 액세스합니까? (0) | 2020.07.17 |
CSS에서 이미지 위에 텍스트를 배치하는 방법 (0) | 2020.07.17 |
C #의 정수 나누기가 왜 실수가 아닌 정수를 반환합니까? (0) | 2020.07.17 |