MEF - 加载依赖项

MEF - Loading dependencies

我正在使用 .net 核心开发 MEF 插件。该插件使用 Entity Framework,并且只有插件项目引用 Entity Framework。我创建了 CompositionContainer,但是当我访问该插件时出现此异常:

Could not load file or assembly 'Microsoft.EntityFrameworkCore,

我有一个定义接口的项目:

namespace MyInterfaces
{
    public interface IShowMessage
    {
        void ShowMessage();
    }
}

主项目加载插件:

namespace MainApp
{
    public class DoWork
    {
        private CompositionContainer _container;
        [Import(typeof(IShowMessage))]
        public IShowMessage MyMessage;
        public DoWork()
        {
            var catalog = new AggregateCatalog();
            catalog.Catalogs.Add(new AssemblyCatalog(GetOtherAssembly()));
            _container = new CompositionContainer(catalog);
            _container.ComposeParts(this);
            MyMessage.ShowMessage();
        }
        private Assembly GetOtherAssembly()
        {
            var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(Directory.GetCurrentDirectory() + @"\..\..\..\..\MyPlugin\bin\debug\netstandard2.1\MyPlugin.dll");
            return assembly;
        }
    }
}

以及实现该接口的插件项目:

namespace MyPlugin
{
    [Export(typeof(IShowMessage))]
    public class ShowComplexMessage : IShowMessage
    {
        public void ShowMessage()
        {
            DbSet<String> str;
            Console.Write("Complex Message");
        }
    }
}

插件参考 EntityFramework 中的行 'DbSet str;'。如果我注释掉这一行,它会正常工作。

我注意到我的插件项目的 bin 文件夹没有 EntityFramework dll。如果我使用 dotnet publish,我可以生成 EntityFramework dll,但这并不能解决问题。 如果我显式加载 'Microsoft.EntityFrameworkCore'。我在 ComposeParts 行上遇到异常,告诉我它无法加载 Entity Framework 使用的程序集。

我已经尝试将所有 DLL 添加到目录中,但有些无法加载(可能是绑定重定向?)。我认为我正在为一些常见且可能已解决的问题走上错误的道路。 ***编辑——这就是 DirectoryCatalog 所做的,但没有帮助。 ***

我也尝试过使用反射创建插件实例,但我遇到了类似的错误。

如何使用插件依赖项加​​载 MEF 插件?

请试试这个:

public class ModuleAssemblyLoadContext : AssemblyLoadContext
{
    private readonly AssemblyDependencyResolver resolver;

    internal ModuleAssemblyLoadContext(string assemblyPath) : base(true)
    {
        resolver = new AssemblyDependencyResolver(assemblyPath);

        ResolvingUnmanagedDll += OnResolvingUnmanaged;

        Resolving += OnResolving;
    }

    private IntPtr OnResolvingUnmanaged(Assembly assembly, string unmanagedName)
    {
        string unmanagedPath = resolver.ResolveUnmanagedDllToPath(unmanagedName);

        return unmanagedPath != null ? LoadUnmanagedDllFromPath(unmanagedPath) : IntPtr.Zero;
    }

    private Assembly OnResolving(AssemblyLoadContext context, AssemblyName assemblyName)
    {
        string assemblyPath = resolver.ResolveAssemblyToPath(assemblyName);

        return assemblyPath != null ? LoadFromAssemblyPath(assemblyPath) : null;
    }
}

您的代码中的下一个:

    private Assembly GetOtherAssembly()
    {
        string path = Directory.GetCurrentDirectory() + @"\..\..\..\..\MyPlugin\bin\debug\netstandard2.1\MyPlugin.dll";

        ModuleAssemblyLoadContext context = new ModuleAssemblyLoadContext(path);

        return context.LoadFromAssemblyPath(path);
    }

当然,请确保插件所需的任何依赖项都存在于插件 dll 所在的文件夹中。

您可以在此处找到更完整的实现:

https://github.com/qube7/qcomposite/blob/master/Qube7.Composite/Hosting/AssemblyModule.cs