Рассмотрим приложение .NET Core, которое ссылается на пакет NuGet.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MyPackage" Version="1.0.0" />
</ItemGroup>
</Project>
Если мой код ссылается на тип в MyPackage
, тогда будет загружена сборка MyPackage
.Если я распечатаю все ссылки или загруженные сборки, то они появятся.
static void Main(string[] args)
{
// Because I have a reference to a type in MyPackage, the assembly
// is loaded and will be printed out by both foreach statements below.
var throwaway = typeof(MyPackage.Cars);
foreach (var an in Assembly.GetEntryAssembly().GetReferencedAssemblies())
{
WriteLine(an.Name);
}
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
WriteLine(assembly.FullName);
}
}
Однако, если я избавлюсь от этой строки throwaway
, то сборка будет не загружена ,и поэтому недоступен ни GetReferencedAssemblies
, ни GetAssemblies
.
. В .NET Framework возникла та же проблема, и исправление обычно состояло в том, чтобы прочитать все сборки в исполняемой папке и загрузить их вручную - что-тонапример:
Directory
.GetFiles(executingFolder, "*.dll", SearchOption.TopDirectoryOnly)
.Select(AssemblyLoadContext.Default.LoadFromAssemblyPath));
Однако .NET Core будет загружать сборки из других мест (таких как кеш NuGet - я пока не нашел исчерпывающего описания нового процесса связывания), поэтому приведенное вышеподход не сработает.
Вопрос
Итак, мой вопрос: как я могу динамически загрузить все библиотеки DLL, на которые ссылается мой файл csproj (как NuGet PackageReferences).Мой вариант использования довольно эзотерический, поэтому я не думаю, что подойдет какой-либо другой механизм.
Справочная информация
Хорошо, поэтому кто-то спросит, каков мой вариант использования, так что вот.
У нас есть набор интерфейсов, которые определяют сообщения (IAuditEvent, IValidationEvent, такого рода вещи).У нас также есть различные реализации этих интерфейсов для различных форматов сериализации (Protobuf, XML, JSON и т. Д.).Каждый из них представляет собой отдельный пакет NuGet (MyMessages.Proto, MyMessages.Xml).
У нас есть фабрика, которая создаст соответствующую реализацию (factory.Create<IAuditEvent>()
), но она делает это с помощью отражения - например, фабрика прототиповнаходит класс, который реализует IAuditEvent
, но также является сгенерированным Protobuf классом.Это не может работать, если сборка не была загружена в первую очередь ...