簡體   English   中英

如何簽入代碼,哪些程序集被引用但未加載? (.NET 6.0)

[英]How to check in code, which assemblies are referenced but not loaded? (.NET 6.0)

更新:

這個問題比我想象的更難解釋。

  1. 我有2個項目。 (.NET 6.0)
  2. 每個項目是一個 NuGet package。
  3. 包不能相互依賴。 (每一個都必須能夠單獨使用。)
  4. 如果 package 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM