[英]How to check in code, which assemblies are referenced but not loaded? (.NET 6.0)
更新:
這個問題比我想象的更難解釋。
B
檢測到 package A
被引用(我的意思是在.csproj
文件中使用<ProjectReference>
或<Package Reference>
標記- 它應該從它加載 ZEFE90A8E604A77C840E8Z8D03 方法並執行一個方法。到目前為止,我已經這樣做了:
(包B代碼)
try {
var assembly = Assembly.Load("A");
var type = assembly.GetTypes.FirstOrDefault(t => t.Name == "MyKnownType");
var instance = (IApiOfA)Activator.CreateInstance(t);
instance.MethodOfA(someDataIHaveInB);
}
catch { }
我討厭濫用異常。 我的問題是如何跳過異常部分。
查詢AppDomain.CurrentDomain
沒有幫助 - 它只獲取 LOADED 程序集。 Assembly.GetEntryAssembly().GetReferencedAssemblies()
也不起作用,當我顯式加載它時,它甚至不顯示我的目標程序集。 AppDomain.CurrentDomain.Evidence
在 .NET 6.0 中不可用。
有什么線索嗎?
另一個更新:這: 在加載之前檢查程序集是否按名稱存在
正如其他人所說:例外並不總是那么糟糕。 也許它們不是最優雅的方式,但有一個權衡。 一項簡單的檢查將在應用程序開發中節省大量時間。 package 所做的事情很容易被忽視,並導致浪費大量時間來弄清楚為什么它不起作用。 現在,當 A 和 B 包含在項目中時,將始終進行正確的交互,並且兩者都不會失敗。 如果只有其中一個包 - 沒有問題,則問題不存在。 如果兩者都使用,它們會合作。 所以我只是在尋找一個微優化:)
您將需要一個自定義構建步驟,將所有引用的列表嵌入到生成的可執行文件中。 Microsoft 工具不會,它們只為那些實際使用和需要的依賴項發出元數據(盡管它們實際上不必在運行時存在,由於依賴項的延遲加載,任何不消耗缺少的依賴項的方法都可以仍然可以正常運行)。
在項目文件中添加更多<PackageReference>
條目不會導致編譯器 output 發生任何更改,它只是允許您使用它們編寫代碼,而該代碼的存在會影響 output。
我當前的解決方案,在 Windows 和 Linux 上進行了測試,使用單個文件構建。
/// <summary>
/// Resolves available API members.
/// </summary>
internal static class ApiResolver {
/// <summary>
/// Gets an instance of the specified type.
/// If it's not already loaded, the target assembly will be loaded.
/// </summary>
/// <typeparam name="TInterface">Type interface.</typeparam>
/// <param name="assemblyName">Assembly name.</param>
/// <param name="typeName">Type name.</param>
/// <returns>Instance or null if not found.</returns>
public static TInterface? GetInstance<TInterface>(string assemblyName, string typeName) where TInterface : class {
Type? type;
try {
var assembly = Assembly.Load(assemblyName);
type = assembly.GetType(typeName);
}
catch { return null; }
return type is null ? null : (TInterface?)Activator.CreateInstance(type);
}
}
如果無法獲取實例,則返回 null。 所以它可以像這樣很好地使用:
var myTarget = ApiResolver.GetInstance<IMyTargetApi>("OtherModule", "TheClass");
myTarget?.DoSomeStuff(withSomeData);
當然,要求目標 class 必須實現已知接口。 但是我的包裹滿足了這個要求。 如果不能滿足,它仍然可以通過使用Reflection
來解決,但這會很麻煩。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.