Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-如何在两个不同的DLL中引用同一类型?_C# - Fatal编程技术网

C#-如何在两个不同的DLL中引用同一类型?

C#-如何在两个不同的DLL中引用同一类型?,c#,C#,我正在开发一个API和使用它的插件。我正在尝试获取在API中引用Mod类的插件类,在API中,当IssignbleFrom(type)为false时。我该怎么办 API.dll Loader.cs ... string[] files = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), "Mods"), "*.dll"); foreach (var file in files)

我正在开发一个API和使用它的插件。我正在尝试获取在API中引用Mod类的插件类,在API中,当IssignbleFrom(type)为false时。我该怎么办

API.dll

Loader.cs

...
string[] files = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), "Mods"), "*.dll");
            foreach (var file in files)
            {
                AddLog(" mod loader : " + file);
                try
                {
                    var asm = Assembly.LoadFile(file);
                    foreach (Type type in asm.GetTypes())
                    {
AddLog("[Debug] " + type + " > " + type.BaseType + " > " + type.IsSubclassOf(typeof(Mod)) + " > " + typeof(Mod).IsAssignableFrom(type));
                        if (type.IsSubclassOf(typeof(Mod)) && type != typeof(Mod))
                        {
                            Mod mod = (Mod) Activator.CreateInstance(type);
                            mod.Register();

                            AddLog(" Mod Loaded : " + type);
                        }
                    }
                }
                catch (Exception e)
                {
                    AddLog(" Failed to create instance of mod.\n" + e.ToString());
                }
...
Mod.cs

namespace SLModder {
    public abstract class Mod {
        public abstract void Register();
    }
}
Plugin.dll

Main.cs

namespace PracticePlugin {
    public class Main : Mod 
    {
        public override void Register() {
            ServerConsole.AddLog("Plugin Enabled");
        }
    }
}
控制台

[Debug] PracticePlugin.Main > SLModder.Mod > false > false

TLDR:LoadFile
LoadFile
几乎肯定是为您的用例加载程序集的错误方式

详细解释:

将程序集加载到程序集上下文中;不同上下文中的程序集被视为不同的程序集,因此它们的所有类型也不同

例如,使用
Load
加载的程序集被视为与通过
LoadFrom
加载的程序集不同的程序集,即使这些程序集的100%字节相等

如果不正确地使用
Load
LoadFrom
LoadFile
,则很容易出现这样的情况:内存中有两个类型相同的文件,但它们的比较结果不相等调试问题的第一步应该是确保将程序集加载到正确的上下文中,以防止出现这种混乱的情况

我在处理插件基础设施时犯了这个错误;诊断起来可能相当棘手

有关此主题的更多信息,请参阅;如果我没记错的话,Suzanne是汇编加载逻辑的实现者之一

另请参见
LoadFile
,上的文档,其中说明:

使用LoadFile方法加载和检查具有相同标识但位于不同路径中的程序集。LoadFile不会像LoadFrom方法那样将文件加载到LoadFrom上下文中,也不会使用加载路径解析依赖项。LoadFile在这种有限的场景中很有用,因为LoadFrom不能用于加载具有相同标识但不同路径的程序集;它将只加载第一个这样的程序集

另请参见,其中指出:

LoadFile(String)方法通过实例化最基本的AssemblyLoadContext来隔离它加载的程序集。它有一个简单的隔离方案,将每个程序集加载到其自己的AssemblyLoadContext中,而不进行依赖项解析

简而言之:问题很可能是因为程序集被加载到了意外的不同上下文中。您需要确保要相同的所有对程序集的引用都加载到适当的上下文中



所有的话:你应该强烈地考虑使用MEF或MAF,而不是试图翻滚自己的插件基础结构。有关详细信息,请参阅。

您试图实现的目标是什么?为什么dll会这样加载?基本上,我要问的是:您是否在不同的DLL中两次声明同一类型?否则,您可以只引用plugin.dllPlugin.dll引用API.dll作为引用。Plugin.dll的Main继承了API.dll的Mod。我希望typeof(Mod).IsAssignableFrom(type)或type.IsSubClassof(typeof(Mod))在type为Main.class时返回true(因为Main继承了Mod),但我不理解为什么返回false。