AssemblyLoadContext, динамически загружать сборку, создавать экземпляр объекта и приводить к общему интерфейсу. - PullRequest
0 голосов
/ 02 октября 2019

Я пытаюсь загрузить сборку с AssemblyLoadContext (существует с версии 3.0 netcore), создать экземпляр объекта и привести этот объект к интерфейсу, но я получаю ошибку исключения приведения.

Интерфейс используется совместно проектом, который загружает сборку, и созданной реализацией. Объект, по-видимому, создан правильно, но я получаю неожиданную ошибку при выполнении (T)instance.

Попытка с наблюдателем Я могу правильно привести экземпляр к интерфейсу, следуя коду, который я использую, и скриншоту наблюдателя:

private (ExecutionAssemblyLoadContext, T) LoadTheAssemblyAndInstance<T>(string assemblyName, string typeNameToInstance)
{
    var basePath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
    var assemblyContext = new ExecutionAssemblyLoadContext($"{basePath}/{assemblyName}.dll");
    var assembly = assemblyContext.LoadFromAssemblyPath($"{basePath}/{assemblyName}.dll");
    var externalCodeEvent = typeNameToInstance != null ? assembly.ExportedTypes
        .Where(x => x.FullName == typeNameToInstance)
        .Single() : assembly.ExportedTypes.First();
    var instance = Activator.CreateInstance(
            externalCodeEvent,
            _defaultConstructorParameters
        );
    return (assemblyContext, (T)instance);
}

enter image description here

это полное сообщение об исключении:

System.InvalidCastException: 'Невозможно привести объект типа' Expriva.NewWorkflow.BPMN.ExecutionCodeTest.ExecutionContractTest 'для ввода'Expriva.NewWorkflow.ExternalShared.Interfaces.IExecutionContract'. '

На следующем снимке экрана показано, что T реализован экземпляром enter image description here

1 Ответ

0 голосов
/ 02 октября 2019

AssemblyLoadContext для поддержки динамической загрузки и выгрузки кода создает отдельный контекст для загрузки кода и его зависимостей в своем собственном экземпляре AssemblyLoadContext.

Проблема заключалась в том, что в реализации ExecutionAssemblyLoadContext зависимости были разрешены и изолированы,Используя реализацию по умолчанию, подписанную документацией AssemblyLoadContext, общие типы не будут изолированы. После правильной реализации, чтобы использовать для обмена интерфейсом.

public class ExecutionAssemblyLoadContext : AssemblyLoadContext
{
    public ExecutionAssemblyLoadContext() : base(isCollectible: true)
    {
    }

    protected override Assembly Load(AssemblyName name)
    {
        return null;
    }
}
...