[解決済み] 現在ロードされているアセンブリをループで処理する方法は?
質問
私の ASP.NET アプリケーションに、データベース接続の検証、現在の appSettings と ConnectionStrings の表示などを行う "diagnostics" ページがあります。 このページのセクションでは、全体を通して使用される重要な型のアセンブリ バージョンが表示されますが、ロードされたすべてのアセンブリのバージョンを効果的に表示する方法が分かりませんでした。
をすべて把握するための最も効果的な方法は何でしょうか。
を把握する最も効果的な方法は何ですか?
アセンブリを把握する最も効果的な方法は何ですか?
注意: 私は、特定のディレクトリ内の *.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
を付けてください。このコードは共有の静的グローバル変数を参照して魔法をかけるので、現在デフォルトではスレッドセーフではありません。
関連
-
[解決済み】「The breakpoint will not currently be hit」を改善するには?このドキュメントにはシンボルが読み込まれていません。" という警告はどうすれば改善されますか?
-
[解決済み】XAMLにSystem.Stringを埋め込む
-
[解決済み] アセンブリから型を読み込めなかったエラー
-
[解決済み] <Database> コンテキストを支えるモデルが、データベース作成後に変更されました。
-
[解決済み] "ItemsSourceを使用する前に、Itemsコレクションを空にする必要があります。"
-
[解決済み] Visual Studioの "ターゲットフレームワーク "が見つからない
-
[解決済み] リファレンスの追加にSystem.Web.Mvcが表示されないのはなぜですか?
-
[解決済み] NetFx45WebLinkとNetFx45RedistLinkの違いは何ですか?
-
[解決済み] 辞書を値で並べ替えるにはどうしたらいいですか?
-
[解決済み] LINQクエリでToList()とToArray()のどちらを呼び出すのが良いですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】警告。同じ依存アセンブリの異なるバージョン間で競合が見つかりました。
-
[解決済み] VB.NETでプログラムパスを取得する?
-
[解決済み] VS2017/2015 で .xproj ファイルを開く方法
-
[解決済み] ファイルまたはアセンブリ 'System.Data.SQLite' をロードできませんでした。
-
[解決済み] gacutil.exeはどこですか?
-
[解決済み] ファイルまたはアセンブリをロードできませんでした 操作がサポートされていません。(HRESULT: 0x80131515 からの例外)
-
[解決済み] "SSL/TLSセキュアチャネルの信頼関係を当局と確立できませんでした "の解決方法
-
[解決済み] terminationGracePeriodSeconds not
-
[解決済み] .net の OOM 問題を解決する必要があります。
-
[解決済み] .NETにおけるstructとclassの違いは何ですか?