简体   繁体   English

AssemblyLoadContext找不到基于类型的程序集

[英]AssemblyLoadContext cannot find in assembly based on type

I cannot seem to get a DefinedType based on a interface (IStartupPlugin), it seems to work with AssemblyLoadContext.Default.LoadFromAssemblyPath however when using my own class it doesn't :( 我似乎无法获得基于接口(IStartupPlugin)的DefinedType,它似乎可以与AssemblyLoadContext.Default.LoadFromAssemblyPath一起使用,但是当使用我自己的类时,它不是:(

var raw = AssemblyLoadContext.Default.LoadFromAssemblyPath(pluginPath + Path.DirectorySeparatorChar + fqName + ".dll");
var raw2 = assemblyContext.LoadFromAssemblyPath(pluginPath + Path.DirectorySeparatorChar + fqName + ".dll");

bool hasDefined = raw.DefinedTypes
                     .Where(x => typeof(IStartupPlugin).IsAssignableFrom(x) && x != null && x != typeof(IStartupPlugin))
                     .Any();

bool hasDefined2 = raw2.DefinedTypes
                       .Where(x => typeof(IStartupPlugin).IsAssignableFrom(x) && x != null && x != typeof(IStartupPlugin))
                       .Any();
public class PluginAssemblyContext : AssemblyLoadContext
{
    private readonly AssemblyDependencyResolver _resolver;

    public PluginAssemblyContext(string mainAssemblyToLoadPath) : base(isCollectible: true)
    {
        _resolver = new AssemblyDependencyResolver(mainAssemblyToLoadPath);
        this.LoadFromAssemblyPath(mainAssemblyToLoadPath);
    }

    protected override Assembly Load(AssemblyName name)
    {
        string assemblyPath = _resolver.ResolveAssemblyToPath(name);
        if (assemblyPath != null)
        {
            return LoadFromAssemblyPath(assemblyPath);
        }

        return null;
    }
}
hasDefined = true
hasDefined2 = false

Both of them is expected to have true as value hasDefined and hasDefined2 由于值hasDefinedhasDefined2都期望它们都为true

It's usually a bad practice to run such code within a constructor. 在构造函数中运行此类代码通常是一种不好的做法。 Define a static (extension) method in a static class then load the desired assembly from anywhere in your app using an instance of your custom PluginAssemblyContext class. 在静态类中定义静态(扩展)方法,然后使用自定义PluginAssemblyContext类的实例从应用程序中的任何位置加载所需的程序集。 Concretely, try this: 具体而言,请尝试以下操作:

public class PluginAssemblyContext : AssemblyLoadContext
{
    private readonly AssemblyDependencyResolver _resolver;

    public PluginAssemblyContext(string mainAssemblyToLoadPath) : base(isCollectible: true)
    {
        _resolver = new AssemblyDependencyResolver(mainAssemblyToLoadPath);
    }


    protected override Assembly Load(AssemblyName name)
    {
        string assemblyPath = _resolver.ResolveAssemblyToPath(name);
        if (assemblyPath != null)
        {
            return LoadFromAssemblyPath(assemblyPath);
        }

        return null;
    }
}

Define this class somewhere within a namespace with proper using s... 适当使用 S某处一个命名空间中定义这个类...

public static class PluginAssemblyContextExtensions
{

    public static Assembly FromAssemblyPath(this AssemblyLoadContext context, string path)
    {

        return context.LoadFromAssemblyPath(path);

    }

}

...from somewhere else (preferably within a static method/constructor), call the above code when your app has finished starting. ...从其他地方(最好是在静态方法/构造函数中),在应用程序启动完成后调用上述代码。 I didn't have a chance to test this but I suspect the smell of your code comes from within the PluginAssemblyContext constructor you defined. 我没有机会进行测试,但是我怀疑您代码的味道来自您定义的PluginAssemblyContext构造函数内。 Please let me know if I'm right (or wrong). 请让我知道我是对还是错。

It seems I have goofed with the creation of the assembly resolver! 似乎我对汇编解析器的创建感到迷惑! I used the path to the '.dll' file (mainAssemblyToLoadPath), however it seems like it asked for the path to the plugin directory (main directory), or so I guessed it seems to work fine now :) 我使用了“ .dll”文件(mainAssemblyToLoadPath)的路径,但是似乎它要求插件目录(主目录)的路径,所以我猜它现在似乎可以正常工作了:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM