我正在使用 Dotnet 6 在 ASP.NET 上實作 C# 框架。我希望框架的一部分可以被外部方擴展;他們只需要實作幾個類,我們可以通過 Nuget 或直接程式集參考來集成他們的作業。
他們需要完成的部分作業是注冊類,這樣他們就可以定義他們的引擎應該如何注冊到依賴注入容器中。這是我期望第 3 方提供的示例:
public class EchoServiceRegistration : IRegisterDI
{
public IServiceCollection Register(IServiceCollection serviceCollection)
{
serviceCollection.TryAddSingleton<EchoEngine>();
return serviceCollection;
}
}
在消費應用程式中,我正在尋找使用 AppDomain 類實作 IRegisterDI 介面的所有類,這是對這個 SO 答案https://stackoverflow.com/a/26750/2573109的重復。(注意:我切換到使用基于名稱的匹配只是為了進行故障排除,一旦正確解決,我會將其改回更好的實作):
List<Type> allRegistrationClasses = AppDomain
.CurrentDomain
.GetAssemblies()
.SelectMany(it => it.GetTypes())
.Where(tp => tp.GetInterfaces()
.Any(inter => inter.Name == nameof(IRegisterDI)))
.ToList();
如所寫,這將回傳 0 個型別。
在下一次故障排除迭代中,我證明了注冊類可供呼叫者使用。因此,我手動創建了EchoServiceRegistration該類的一個實體,如下所示。這一次,AppDomain 包含一個 EchoServiceRegistration 條目(如預期的那樣)。
var allRegistrationClasses = AppDomain.CurrentDomain.GetAssemblies().SelectMany(it => it.GetTypes()).Where(tp => tp.GetInterfaces().Any(inter => inter.Name == nameof(IRegisterDI))).ToList();
var echoServiceRegistration = new EchoServiceRegistration();
echoServiceRegistration.Register(builder.Services);
if (allRegistrationClasses.Count is not 1) throw new InvalidOperationException(); // Does not throw an exception
為了證明我沒有意外修復某些東西,我將與 Echo Service Registration 相關的兩行注釋掉,并且 allRegistrationClasses 再次包含 0 條記錄。
var allRegistrationClasses = AppDomain.CurrentDomain.GetAssemblies().SelectMany(it => it.GetTypes()).Where(tp => tp.GetInterfaces().Any(inter => inter.Name == nameof(IRegisterDI))).ToList();
// var echoServiceRegistration = new EchoServiceRegistration();
// echoServiceRegistration.Register(builder.Services);
if (allRegistrationClasses.Count is not 1) throw new InvalidOperationException(); // Throws an exception
我的直覺反應是我不明白如何AppDomain確定要加載哪些程式集。我開始閱讀微軟提供的關于它的檔案,但這似乎是一個很深的話題,如果沒有大量的專門閱讀,我不會有更清晰的理解。
在 DI 容器構建期間呼叫它時,如何保證完整的類集可用?如果我可以提供任何額外的細節或清晰度,請告訴我。
uj5u.com熱心網友回復:
在我看來,在您的第一次測驗中,程式集沒有加載到應用程式域中,因為它沒有被使用。
在您的第二次測驗中,您正在手動創建一個實體,因此您正在強制加載程式集。請注意,即使將程式集作為參考添加,除非實際需要,否則不會加載它。
您需要顯式加載要掃描的程式集。這樣做的一種方法是將所有擴展庫都放在一個特定的檔案夾中,然后您可以在注冊之前從該檔案夾中加載它們:
var files = Directory.GetFiles(@"C:\my-framework\extensions");
foreach (var file in files)
{
var extension = Path.GetExtension(file);
if(extension == ".dll")
{
var asm = Assembly.LoadFile(file);
Console.WriteLine($"Loaded extension [{asm.FullName}]");
}
}
加載程式集后,您應該獲得所需的結果。
這是一個過于簡單的例子,但它應該足以讓你繼續前進。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/531718.html
標籤:C#网
上一篇:Blazor授權和身份驗證
